如何为 python 列表中包含字母的字符串添加标签?
How to add labels to strings with letters in python list?
我写了一些工作正常的代码,但我想让它更精确。
这个想法是添加一个字母来显示元素在列表中的出现。初始列表如下所示
['1','2','1','2','1']
我想要
['1a','2a','1b','2b','1c']
我确定有一个快速的答案或功能可以做到这一点,有人知道吗?
我的代码如下:
ancestrals = ['1','2','1','2','1']
uni_a = list(set(ancestrals))
for i in range(len(ancestrals)):
tmp = uni_a.index(ancestrals[i])
if uni_a[tmp][-1].isalpha():
val = ancestrals[i][:1] + chr(ord(uni_a[tmp][-1])+1)
else:
val = ancestrals[i] + "a"
ancestrals[i] = val
while uni_a[tmp] in ancestrals[i:]:
p = ancestrals[i:].index(uni_a[tmp])+ i
ancestrals[p] = val
uni_a[tmp] = ancestrals[i]
print(ancestrals)
ancestrals = ['1','2','1','2','1']
count = {}
for i, anc in enumerate(ancestrals):
cnt = count.get(anc, 0)
count[anc] = cnt + 1
ancestrals[i] += chr(ord('a') + cnt)
print (ancestrals)
# --> ['1a', '2a', '1b', '2b', '1c']
当然,只有当每个元素的最大计数为 26(字母“z”)时才有效。
如果你想要简洁但有点不透明,这里是 aa(诚然是半开玩笑的)版本:
from collections import Counter
def decorate(a):
cnt = Counter()
return [f'{x}{chr(ord("a") + i)}' for x in a for i in [cnt.update(x) or cnt[x] - 1]]
示例:
>>> decorate(['1','2','1','2','1'])
['1a', '2a', '1b', '2b', '1c']
虽然 很好,但它很不透明,正如@PierreD 所说。
这是一种更清晰的方法,同时遍历 ancestrals
列表而不是就地修改它。用于每个项目的最后一个字母的序数存储在 last_letters
字典中。对于每个 item
,都会检查它并使用下一个字母。默认值是 a
之前的任何内容(`
反引号),因此在向其添加 1 时得到 'a'。
ancestrals = ['1','2','1','2','1']
last_letters = {}
uni_a = [] # will hold the result
default = ord('a') - 1 # char before 'a' is '`'
for item in ancestrals:
prev_ord = last_letters.get(item, default) # these two lines can be
next_letter = chr(prev_ord + 1) # combined into one
uni_a.append(item + next_letter)
last_letters[item] = prev_ord + 1
print(uni_a)
# ['1a', '2a', '1b', '2b', '1c']
我写了一些工作正常的代码,但我想让它更精确。
这个想法是添加一个字母来显示元素在列表中的出现。初始列表如下所示
['1','2','1','2','1']
我想要
['1a','2a','1b','2b','1c']
我确定有一个快速的答案或功能可以做到这一点,有人知道吗?
我的代码如下:
ancestrals = ['1','2','1','2','1']
uni_a = list(set(ancestrals))
for i in range(len(ancestrals)):
tmp = uni_a.index(ancestrals[i])
if uni_a[tmp][-1].isalpha():
val = ancestrals[i][:1] + chr(ord(uni_a[tmp][-1])+1)
else:
val = ancestrals[i] + "a"
ancestrals[i] = val
while uni_a[tmp] in ancestrals[i:]:
p = ancestrals[i:].index(uni_a[tmp])+ i
ancestrals[p] = val
uni_a[tmp] = ancestrals[i]
print(ancestrals)
ancestrals = ['1','2','1','2','1']
count = {}
for i, anc in enumerate(ancestrals):
cnt = count.get(anc, 0)
count[anc] = cnt + 1
ancestrals[i] += chr(ord('a') + cnt)
print (ancestrals)
# --> ['1a', '2a', '1b', '2b', '1c']
当然,只有当每个元素的最大计数为 26(字母“z”)时才有效。
如果你想要简洁但有点不透明,这里是 aa(诚然是半开玩笑的)版本:
from collections import Counter
def decorate(a):
cnt = Counter()
return [f'{x}{chr(ord("a") + i)}' for x in a for i in [cnt.update(x) or cnt[x] - 1]]
示例:
>>> decorate(['1','2','1','2','1'])
['1a', '2a', '1b', '2b', '1c']
虽然
这是一种更清晰的方法,同时遍历 ancestrals
列表而不是就地修改它。用于每个项目的最后一个字母的序数存储在 last_letters
字典中。对于每个 item
,都会检查它并使用下一个字母。默认值是 a
之前的任何内容(`
反引号),因此在向其添加 1 时得到 'a'。
ancestrals = ['1','2','1','2','1']
last_letters = {}
uni_a = [] # will hold the result
default = ord('a') - 1 # char before 'a' is '`'
for item in ancestrals:
prev_ord = last_letters.get(item, default) # these two lines can be
next_letter = chr(prev_ord + 1) # combined into one
uni_a.append(item + next_letter)
last_letters[item] = prev_ord + 1
print(uni_a)
# ['1a', '2a', '1b', '2b', '1c']