2

对于此列表:

['a','a','a,'b','b','c']

我想拥有:

['a1','a2','a3','b1','b2','c']

目的是获取包含不同项目的列表。( len(set(my_list)) == len(my_list))

可以假设列表已排序。

不是每个项目都必须出现一次以上(比如这里的“c”,在这种情况下离开它)

有很多方法可以做到这一点,我没有想到一个“pythonic”的方法。

4

6 回答 6

4

使用collections.Counteritertools.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']
于 2013-06-28T16:44:43.613 回答
1

尝试这个:

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()将解决它。

于 2013-06-28T16:44:36.787 回答
1

由于其他人都在发布他们自己的版本,这里是我的使用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']

请注意,不保留原始列表顺序。

于 2013-06-28T17:23:51.357 回答
0

这是一个单线......效率不高或不推荐!

给定输入:

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)]
于 2013-06-28T17:22:23.503 回答
0

您可以使用 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))
于 2013-06-28T17:11:27.820 回答
0
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
于 2013-06-28T16:51:11.000 回答