在Python中将相同的字符串附加到字符串列表中

292

我想把一个字符串添加到包含在列表中的每个字符串末尾,然后创建一个新列表包含所有已完成的字符串。例如:

list1 = ['foo', 'fob', 'faz', 'funk']
string = 'bar'

*magic*

list2 = ['foobar', 'fobbar', 'fazbar', 'funkbar']

我尝试使用for循环和列表推导式,但是都不行。像往常一样,非常感谢任何帮助。


27
因为list是内置函数,所以将其赋值给变量是不明智的。 - Noufal Ibrahim
我的问题是关于如何根据列表中的位置将不同的字符串附加到字符串列表中的。这个问题可以在stackoverflow上找到答案。 - Gonçalo Peres
13个回答

469

最简单的方法是使用列表推导式:

[s + mystring for s in mylist]

请注意,我避免使用内置名称,如list,因为这会掩盖内置名称,这是非常不好的。

此外,如果您实际上不需要列表,只需要迭代器,那么生成器表达式可能更有效(尽管在短列表上不太重要):

(s + mystring for s in mylist)

这些功能非常强大,灵活且简洁。每个优秀的Python程序员都应该学习使用它们。


10
如果想要懒加载,可以使用生成表达式 (s + mystring for s in mylist) - Noufal Ibrahim
3
非常感谢,那绝对解决了问题。我还在努力理解列表推导式,如果你知道一个好的教程,请告诉我。在列表中的每个项目之前都有一个u',那是表示Unicode编码吗? - Kevin
4
@Kevin,这是一个关于Unicode字符串的教程,http://docs.python.org/tutorial/introduction.html#tut-unicodestrings - tgray
如果您需要从列表中获取索引,可以执行["{}) {}".format(i, s) for i, s in enumerate(mylist)] - Vapid
1
需要注意的是:如果你在"s"之前添加"mystring",而不是之后,它将把"mystring"连接到"s"的开头。就像这样list2 = ["mystring" + s for s in mylist]=list2 = ['barfoo', 'barfob', 'barfaz', 'barfunk'] - Paul Tuckett
1
如果实际上不需要一个新列表,你可以使用切片赋值: list[:] = [x + string for x in list] - PYB

42
my_list = ['foo', 'fob', 'faz', 'funk']
string = 'bar'
my_new_list = [x + string for x in my_list]
print my_new_list

这将打印:

['foobar', 'fobbar', 'fazbar', 'funkbar']

9

map 对于我来说似乎是正确的工具。

my_list = ['foo', 'fob', 'faz', 'funk']
string = 'bar'
list2 = list(map(lambda orig_string: orig_string + string, my_list))

请参阅此部分中有关函数式编程工具的更多map示例。


这似乎是最快的解决方案。如果您将使用多个列表重复此过程,可以通过仅定义一次 lambda 函数并将其用于每个列表来进一步加速。 - Leland Hepworth

9

这是一个使用pandas的简单答案。

import pandas as pd
list1 = ['foo', 'fob', 'faz', 'funk']
string = 'bar'

list2 = (pd.Series(list1) + string).tolist()
list2
# ['foobar', 'fobbar', 'fazbar', 'funkbar']

请将变量名从list和string更改为其他名称。list是Python内置类型。 - sagi
这个解决方案完成所需的时间比提供的其他解决方案要长得多。 - Leland Hepworth

7

更多选项的更新

以下是我遵循的一些方法,当然还有其他方法。

方法1:

list1 = ['foo', 'fob', 'faz', 'funk']
list2 = [ls+"bar" for ls in list1] # using list comprehension
print(list2)

步骤二:

list1 = ['foo', 'fob', 'faz', 'funk']
list2 = list(map(lambda ls: ls+"bar", list1))
print(list2)

方法三:

list1 = ['foo', 'fob', 'faz', 'funk']
addstring = 'bar'
for index, value in enumerate(list1):
    list1[index] = addstring + value #this will prepend the string
    #list1[index] = value + addstring #this will append the string

方法4:

list1 = ['foo', 'fob', 'faz', 'funk']
addstring = 'bar'
list2 = []
for value in list1:
    list2.append(str(value) + "bar")
print(list2)

第五种方法:

list1 = ['foo', 'fob', 'faz', 'funk']
list2 = list(map(''.join, zip(list1, ["bar"]*len(list1))))
print(list2)

避免使用关键词作为变量名,例如 'list',将其重命名为 'list1'。


这是一个好建议。另一个建议是使用array_map函数和一个将字符串附加到数组元素的函数... https://www.php.net/manual/zh/function.array-map.php - ROunofF
方法1中有一个小错误:'lsit2' 应该是 'list2'。 - Morten Grum
感谢@MortenGrum,已经更正了。 - Uday Kiran

6

按照 Pythonic 的方式运行以下实验:

[s + mystring for s in mylist]

看起来比像这样使用 for 循环的明显用法快约 35%:

i = 0
for s in mylist:
    mylist[i] = s+mystring
    i = i + 1

实验

import random
import string
import time

mystring = '/test/'

l = []
ref_list = []

for i in xrange( 10**6 ):
    ref_list.append( ''.join(random.choice(string.ascii_lowercase) for i in range(10)) )

for numOfElements in [5, 10, 15 ]:

    l = ref_list*numOfElements
    print 'Number of elements:', len(l)

    l1 = list( l )
    l2 = list( l )

    # Method A
    start_time = time.time()
    l2 = [s + mystring for s in l2]
    stop_time = time.time()
    dt1 = stop_time - start_time
    del l2
    #~ print "Method A: %s seconds" % (dt1)

    # Method B
    start_time = time.time()
    i = 0
    for s in l1:
        l1[i] = s+mystring
        i = i + 1
    stop_time = time.time()
    dt0 = stop_time - start_time
    del l1
    del l
    #~ print "Method B: %s seconds" % (dt0)

    print 'Method A is %.1f%% faster than Method B' % ((1 - dt1/dt0)*100)

结果

Number of elements: 5000000
Method A is 38.4% faster than Method B
Number of elements: 10000000
Method A is 33.8% faster than Method B
Number of elements: 15000000
Method A is 35.5% faster than Method B

5

结合mapformat

>>> list(map('{}bar'.format,  ['foo', 'fob', 'faz', 'funk']))
['foobar', 'fobbar', 'fazbar', 'funkbar']

因此,没有循环变量。 适用于Python 2和3。(在Python 3中可以写成“[*map(...)]”,在Python 2中只能写成“map(...)”)。
如果有人更喜欢模运算表达式:
>>> list(map('%sbar'.__mod__,  ['foo', 'fob', 'faz', 'funk']))
['foobar', 'fobbar', 'fazbar', 'funkbar']

在Python中,如果要在字符串的开头插入内容,可以使用 __add__ 方法。
>>> list(map('bar'.__add__,  ['foo', 'fob', 'faz', 'funk']))
['barfoo', 'barfob', 'barfaz', 'barfunk']

2

稍微扩展一下,即“将字符串列表追加到另一个字符串列表中”:

    import numpy as np
    lst1 = ['a','b','c','d','e']
    lst2 = ['1','2','3','4','5']

    at = np.full(fill_value='@',shape=len(lst1),dtype=object) #optional third list
    result = np.array(lst1,dtype=object)+at+np.array(lst2,dtype=object)

结果:

array(['a@1', 'b@2', 'c@3', 'd@4', 'e@5'], dtype=object)

数据类型 dtype object 可以进一步转换为 str。


更新:您可以避免多次复制相同的符号:at = np.full(fill_value='@',shape=1,dtype=object)或者简单地:at = np.array("@", dtype=object) - Sokolokki

2

自 Python 3.6 开始,使用 f-strings 是最佳实践(而不是使用 format 或使用 + 进行连接)。请参见 PEP498

list1 = ['foo', 'fob', 'faz', 'funk']
mystring = 'bar'

list2 = [f"{s}{mystring}" for s in list1]

1

你可以在Python中使用map内部的lambda函数。编写了一个格雷码生成器。 https://github.com/rdm750/rdm750.github.io/blob/master/python/gray_code_generator.py # 在这里写下你的代码 ''' n-1位码,每个单词前面加0,后跟n-1位反向排序的码,每个单词前面加1。 '''

    def graycode(n):
        if n==1:
            return ['0','1']
        else:
            nbit=map(lambda x:'0'+x,graycode(n-1))+map(lambda x:'1'+x,graycode(n-1)[::-1])
            return nbit

    for i in xrange(1,7):
        print map(int,graycode(i))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接