替换Python列表中的重复字符串

时间:2021-04-17 20:44:00

I have a Python list and there is exactly one element which is repeated thrice. I want to replace them with unique element.

我有一个Python列表,并且只有一个元素重复三次。我想用独特的元素替换它们。

my_list = [,...,'future_use',...,'future_use',..'future_use',...]

Expected o/p:

预期的o / p:

[,...,'future_use1',...,'future_use2',..'future_use3',...]

I tried using list comprehension:

我尝试使用列表理解:

count = my_list.count("future_use")
for i in range(1, count+1):
    my_list = [item.replace("future_use","future_use%r" %i,i) for item in my_list]

However, I'm not getting desired output.Can someone point me to the correct procedure?

但是,我没有得到理想的输出。有人能指出我正确的程序吗?

6 个解决方案

#1


4  

You could use Counter and defaultdict from collections and count from itertools to make this a little shorter; whether it's clearer depends on how much time you've spent with Python. Patterns like this are used a lot, though, and are worth being familiar with..

您可以使用集合中的Counter和defaultdict以及来自itertools的计数来缩短它;是否更清楚取决于你花在Python上的时间。像这样的模式经常被使用,并且值得熟悉。

(python 3.6 style here, using f-strings)

(python 3.6 style,使用f-strings)

from collections import Counter, defaultdict
import itertools

seq = ["a", "future_use", "b", "b", "future_use", "c", "future_use"]

counts = Counter(seq)
suffix_counter = defaultdict(lambda: itertools.count(1))
seq2 = [elem if counts[elem] == 1 else elem + f'_{next(suffix_counter[elem])}'
        for elem in seq]

gives me

给我

>>> seq2
['a', 'future_use_1', 'b_1', 'b_2', 'future_use_2', 'c', 'future_use_3']

#2


2  

Here is the general approach:

这是一般方法:

my_list = ['foo', 'foo', 'whatever', 'whatever', 'nevermind', 'foo']

new_list = [] 
counts = {}

for el in my_list:
    temp_count = counts.get(el, 0) + 1
    counts[el] = temp_count 

    if temp_count == 1 and my_list.count(el) == 1:
        new_list.append(el)
    else:
        new_list.append(el + str(temp_count))

print(new_list) # ['foo1', 'foo2', 'whatever1', 'whatever2', 'nevermind', 'foo3']

Rather slow, but pretty straightforward.

相当慢,但相当简单。


UPD

UPD

Adapting the @DSM's great answer, this can be also implemented as follows:

调整@ DSM的最佳答案,也可以按如下方式实现:

my_list = ['foo', 'foo', 'whatever', 'whatever', 'nevermind', 'foo']

from collections import Counter

ranges = {k:[str(i + 1) for i in range(v)] for k,v in Counter(my_list).items()}
new_list = [el if ranges[el] == ['1'] else (el + ranges[el].pop(0)) for el in my_list]

print(new_list) # ['foo1', 'foo2', 'whatever1', 'whatever2', 'nevermind', 'foo3']

#3


1  

You can try this one:

你可以尝试这个:

myList = ['future_use','future_use','future_use']

def makeUnique(myList, word):

    counter = 1

    for i in range(0,len(myList)):
        if myList[i] == word:
            myList[i] = word + str(counter)
            counter = counter + 1

makeUnique(myList, 'future_use')
print(myList)

The result is:

结果是:

['future_use1', 'future_use2', 'future_use3']

You can use it for every string element on a list.

您可以将它用于列表中的每个字符串元素。

#4


0  

Try this:

尝试这个:

i = 0
for j, item in enumerate(my_list):
    if item == "future_use":
        my_list[j] = "future_use" + str(i)
        i += 1

#5


0  

Maybe using a generator here is a bit overkill but its a useful technique to know if you use list comprehensions and generators.

也许在这里使用一个生成器有点矫枉过正,但它是一个有用的技术,知道你是否使用列表推导和生成器。

def gen(count):
    for i in range(count):
        yield i+1

my_list = ['mpla', 'future_use','mpla','future_use','future_use','mpla']
count = my_list.count("future_use")
idx = gen(count)
for i in range(count):
    my_list = [item if item!='future_use' 
               else 'future_use' + str(next(idx)) for item in my_list]

print(my_list)

#6


0  

Don't think about more memory efficient, faster, comprehensive and native method.

不要考虑更高效,更快,更全面和本机的方法。

my_list = ['foo', 'bar', 'foo', 'foobar', 'bar', 'foo', 'foo', 'bar', 'foobar']
keywords = {}
for i, item in enumerate(my_list):
    if item in keywords:
        my_list[i] = item + str(keywords[item])
        keywords[item] += 1
    else:
        keywords[item] = 1
        my_list[i] = item + '1'

#1


4  

You could use Counter and defaultdict from collections and count from itertools to make this a little shorter; whether it's clearer depends on how much time you've spent with Python. Patterns like this are used a lot, though, and are worth being familiar with..

您可以使用集合中的Counter和defaultdict以及来自itertools的计数来缩短它;是否更清楚取决于你花在Python上的时间。像这样的模式经常被使用,并且值得熟悉。

(python 3.6 style here, using f-strings)

(python 3.6 style,使用f-strings)

from collections import Counter, defaultdict
import itertools

seq = ["a", "future_use", "b", "b", "future_use", "c", "future_use"]

counts = Counter(seq)
suffix_counter = defaultdict(lambda: itertools.count(1))
seq2 = [elem if counts[elem] == 1 else elem + f'_{next(suffix_counter[elem])}'
        for elem in seq]

gives me

给我

>>> seq2
['a', 'future_use_1', 'b_1', 'b_2', 'future_use_2', 'c', 'future_use_3']

#2


2  

Here is the general approach:

这是一般方法:

my_list = ['foo', 'foo', 'whatever', 'whatever', 'nevermind', 'foo']

new_list = [] 
counts = {}

for el in my_list:
    temp_count = counts.get(el, 0) + 1
    counts[el] = temp_count 

    if temp_count == 1 and my_list.count(el) == 1:
        new_list.append(el)
    else:
        new_list.append(el + str(temp_count))

print(new_list) # ['foo1', 'foo2', 'whatever1', 'whatever2', 'nevermind', 'foo3']

Rather slow, but pretty straightforward.

相当慢,但相当简单。


UPD

UPD

Adapting the @DSM's great answer, this can be also implemented as follows:

调整@ DSM的最佳答案,也可以按如下方式实现:

my_list = ['foo', 'foo', 'whatever', 'whatever', 'nevermind', 'foo']

from collections import Counter

ranges = {k:[str(i + 1) for i in range(v)] for k,v in Counter(my_list).items()}
new_list = [el if ranges[el] == ['1'] else (el + ranges[el].pop(0)) for el in my_list]

print(new_list) # ['foo1', 'foo2', 'whatever1', 'whatever2', 'nevermind', 'foo3']

#3


1  

You can try this one:

你可以尝试这个:

myList = ['future_use','future_use','future_use']

def makeUnique(myList, word):

    counter = 1

    for i in range(0,len(myList)):
        if myList[i] == word:
            myList[i] = word + str(counter)
            counter = counter + 1

makeUnique(myList, 'future_use')
print(myList)

The result is:

结果是:

['future_use1', 'future_use2', 'future_use3']

You can use it for every string element on a list.

您可以将它用于列表中的每个字符串元素。

#4


0  

Try this:

尝试这个:

i = 0
for j, item in enumerate(my_list):
    if item == "future_use":
        my_list[j] = "future_use" + str(i)
        i += 1

#5


0  

Maybe using a generator here is a bit overkill but its a useful technique to know if you use list comprehensions and generators.

也许在这里使用一个生成器有点矫枉过正,但它是一个有用的技术,知道你是否使用列表推导和生成器。

def gen(count):
    for i in range(count):
        yield i+1

my_list = ['mpla', 'future_use','mpla','future_use','future_use','mpla']
count = my_list.count("future_use")
idx = gen(count)
for i in range(count):
    my_list = [item if item!='future_use' 
               else 'future_use' + str(next(idx)) for item in my_list]

print(my_list)

#6


0  

Don't think about more memory efficient, faster, comprehensive and native method.

不要考虑更高效,更快,更全面和本机的方法。

my_list = ['foo', 'bar', 'foo', 'foobar', 'bar', 'foo', 'foo', 'bar', 'foobar']
keywords = {}
for i, item in enumerate(my_list):
    if item in keywords:
        my_list[i] = item + str(keywords[item])
        keywords[item] += 1
    else:
        keywords[item] = 1
        my_list[i] = item + '1'