对于此列表:
['a','a','a,'b','b','c']
我想拥有:
['a1','a2','a3','b1','b2','c']
目的是获取包含不同项目的列表。( len(set(my_list)) == len(my_list)
)
可以假设列表已排序。
不是每个项目都必须出现一次以上(比如这里的“c”,在这种情况下离开它)
有很多方法可以做到这一点,我没有想到一个“pythonic”的方法。
使用collections.Counter
和itertools.count
:
>>> from itertools import count
>>> from collections import Counter
>>> lis = ['a','a','a','b','b','c']
>>> c = Counter(lis)
>>> dic = {k: count(1) for k in c}
>>> [x + ( str(next(dic[x])) if c[x]>1 else '') for x in lis]
['a1', 'a2', 'a3', 'b1', 'b2', 'c']
使用itertools.groupby
和生成器功能:
>>> def solve(lis):
for k,g in groupby(lis):
le = list(g)
if len(le) > 1:
for i, x in enumerate(le, 1):
yield x+str(i)
else:
yield k
...
>>> list(solve(lis))
['a1', 'a2', 'a3', 'b1', 'b2', 'c']
尝试这个:
lst = ['a','a','a','b','b','c']
[ e + str(i) for i, e in enumerate(lst) ]
=> ['a0', 'a1', 'a2', 'b3', 'b4', 'c5']
以上将为所有值生成唯一名称,只要您不介意为每个字符串使用不同的数字(例如,b1
如果1
之前使用过,则不会有 a)
编辑
现在问题很清楚了,这是另一个可能的解决方案,使用函数式编程风格:
from collections import Counter
lst = ['a','a','a','b','b','c']
c = Counter(lst)
reduce(lambda a, (k, v): a + ([k + str(i) for i in xrange(1, v+1)] if v > 1 else [k]), c.items(), [])
=> ['a1', 'a2', 'a3', 'c', 'b1', 'b2']
以上将更改在输入列表中找到的原始顺序,但如果这是一个问题,一个简单的sort()
将解决它。
由于其他人都在发布他们自己的版本,这里是我的使用itertools.Counter
:
>>> counts = Counter(original_list)
>>> [k + (str(i+1) if ct > 1 else "") for k, ct in counts.iteritems() for i in xrange(ct)]
['a1', 'a2', 'a3', 'c', 'b1', 'b2']
请注意,不保留原始列表顺序。
这是一个单线......效率不高或不推荐!
给定输入:
A = ['a','a','a','b','b','c']
编写输出:
result = [(x + str(A[:i].count(x)) if A.count(x) > 1 else x) for i, x in enumerate(A)]
您可以使用 itertools 和其他一些内置函数:
import itertools
data = ['a','a','a','b','b','c']
data_lists = [[y + str(x) for x, y in enumerate(it, 1)] for _, it in itertools.groupby(data)]
result = list(itertools.chain.from_iterable((item if len(item) > 1 else item[0][:-1]) for item in data_lists))
L= ['a','a','a','b','b','c']
combined = list()
for item in set(L):
ocr = L.count(item)
if ocr > 1: combined += map(lambda x: item + str(x), range(1,ocr))
else: combined.append(item)
print combined