我希望迭代一个包含重复值的列表。 101有101.A和101.B这是正确的但102开始于102.C而不是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']
答案 0 :(得分:1)
<强>鉴于强>
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
<强>代码强>
简单的双线解决方案
dd = ct.defaultdict(it.count)
print([".".join([room, letters[next(dd[room])]]) for room in room_numbers])
或
dd = ct.defaultdict(lambda: iter(letters))
print([".".join([room, next(dd[room])]) for room in room_numbers])
输出
['101.A', '103.A', '101.B', '102.A', '104.A', '105.A', '106.A', '107.A', '102.B', '108.A']
<强>详情
在第一个示例中,我们使用 itertools.count
作为default factory。这意味着只要将新的房间号添加到defaultdict count()
,就会生成一个新的dd
迭代器。迭代器很有用,因为它们被懒惰地评估并且内存有效。
在列表推导中,每个房间号都会初始化这些迭代器。产生下一个计数器的数字,该数字用作获取字母的索引,结果只是作为每个房间号的后缀加入。
在第二个例子(推荐)中,我们使用字符串的迭代器作为默认工厂。通过在lambda函数中返回迭代器来满足可调用的需求。字符串的迭代器使我们可以简单地调用next()
并直接获取下一个字母。因此,简化了理解,因为不再需要切片letters
。
答案 1 :(得分:0)
天真的方式,只需计算元素在列表中包含的次数,直到该索引为止:
private void getData()
这两个显式的for循环使得二次复杂性突然出现。实际上,进行(1/2)*(N *(N-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']
个计数,而不是每次计算。
dict
这样一来,索引就不会搞乱,而且时间效率更高(以辅助空间为代价)。
答案 2 :(得分: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
现在包含您期望的最终列表
['101.A', '103.A', '101.B', '102.A', '104.A', '105.A', '106.A', '107.A', '102.B', '108.A']
表示给定输入room_numbers
答案 3 :(得分:0)
使用迭代器和理解:
groupby()
.A
,.B
等。
#!/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']