Repeating a list containing duplicate values

I am looking for iteration over a list with duplicate values. 101 has 101A and 101.B, which is true, but 102 starts at 102.C instead of 102.A

import string
room_numbers = ['101','103','101','102','104','105','106','107','102','108']
door_numbers = []
num_count = 0
for el in room_numbers:
    if room_numbers.count(el) == 1:
        door_numbers.append("%s.%s" % (el, string.ascii_uppercase[0]))
    elif room_numbers.count(el) > 1:
        door_numbers.append("%s.%s" % (el, string.ascii_uppercase[num_count]))
        num_count += 1

door_numbers = ['101.A','103.A','101.B','102.C','104.A',
                '105.A','106.A','107.A','102.D','108.A']   
+4
source share
4 answers

Considering

import string
import itertools as it
import collections as ct


room_numbers = ['101','103','101','102','104','105','106','107','102','108']
letters = string.ascii_uppercase

the code

Simple two-line solution

dd = ct.defaultdict(it.count)    
print([".".join([room, letters[next(dd[room])]]) for room in room_numbers])

or

dd = ct.defaultdict(lambda: iter(letters))
print([".".join([room, next(dd[room])]) for room in room_numbers])

Output

['101.A', '103.A', '101.B', '102.A', '104.A', '105.A', '106.A', '107.A', '102.B', '108.A']

More details

In the first example we use itertools.countas default factory . This means that a new iterator count()is created each time a new room number is added to defaultdict dd. Iterators are useful because they are lazily evaluated and memory efficient.

. , , .

() factory. -. next() . , , letters .

+1

, , , :

>>> door_numbers = []
>>> for i in xrange(len(room_numbers)):
...     el = room_numbers[i]
...     n = 0
...     for j in xrange(0, i):
...         n += el == room_numbers[j]
...     c = string.ascii_uppercase[n]
...     door_numbers.append("{}.{}".format(el, c))
...
>>> door_numbers
['101.A', '103.A', '101.B', '102.A', '104.A', '105.A', '106.A', '107.A', '102.B', '108.A']

for-loops . , (1/2) * (N * (N-1)). , dict , .

>>> door_numbers = []
>>> counts = {}
>>> for el in room_numbers:
...     count = counts.get(el, 0)
...     c = string.ascii_uppercase[count]
...     counts[el] = count + 1
...     door_numbers.append("{}.{}".format(el, c))
...
>>> door_numbers
['101.A', '103.A', '101.B', '102.A', '104.A', '105.A', '106.A', '107.A', '102.B', '108.A']

, , ( ).

0

, num_count, , . , .

1. 2. 3. , 4. 64 ascii, 65=A 5. , , door_numbers.

import string
room_numbers = ['101','103','101','102','104','105','106','107','102','108']
door_numbers = []

visited_rooms = []
for room in room_numbers:
    visited_rooms.append(room)
    room_count = visited_rooms.count(room)
    door_value = chr(64+room_count) # Since 65 = A when 1st item is present
    door_numbers.append("%s.%s"%(room, door_value))

door_numbers now contains the final list that you expect, which

['101.A', '103.A', '101.B', '102.A', '104.A', '105.A', '106.A', '107.A', '102.B', '108.A']

for a given entry room_numbers

0
source

Using iterators and concepts:

  • List the numbers to keep the original order.
  • Group numbers by number, first sorted by groupby()
  • For each room in the group add .A, .Betc.
  • Sort by enumeration values ​​from step 1 to restore the original order
  • Extract door numbers, for example. '101.A'

.

#!/usr/bin/env python3

import operator
from itertools import groupby
import string

room_numbers = ['101', '103', '101', '102', '104',
                '105', '106', '107', '102', '108']
get_room_number = operator.itemgetter(1)
enumerated_and_sorted = sorted(list(enumerate(room_numbers)),
                               key=get_room_number)
# [(0, '101'), (2, '101'), (3, '102'), (8, '102'), (1, '103'),
#  (4, '104'), (5, '105'), (6, '106'), (7, '107'), (9, '108')]  
grouped_by_room = groupby(enumerated_and_sorted, key=get_room_number)
# [('101', [(0, '101'), (2, '101')]),
#  ('102', [(3, '102'), (8, '102')]),
#  ('103', [(1, '103')]),
#  ('104', [(4, '104')]),
#  ('105', [(5, '105')]),
#  ('106', [(6, '106')]),
#  ('107', [(7, '107')]),
#  ('108', [(9, '108')])] 
door_numbers = ((order, '{}.{}'.format(room, char))
                for _, room_list in grouped_by_room
                for (order, room), char in zip(room_list,
                                               string.ascii_uppercase))
# [(0, '101.A'), (2, '101.B'), (3, '102.A'), (8, '102.B'),
#  (1, '103.A'), (4, '104.A'), (5, '105.A'), (6, '106.A'),
#  (7, '107.A'), (9, '108.A')] 
door_numbers = [room for _, room in sorted(door_numbers)]
# ['101.A', '103.A', '101.B', '102.A', '104.A',
#  '105.A', '106.A', '107.A', '102.B', '108.A']                                         
0
source

Source: https://habr.com/ru/post/1692685/


All Articles