2010-01-12 2 views
86

Я пытаюсь взять одну строку и добавить ее к каждой строке, содержащейся в списке, а затем добавить новый список с завершенными строками. Пример:Добавление той же строки в список строк в Python

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

*magic* 

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

Я попытался использовать петли и попытался понять список, но это был мусор. Как всегда, любая помощь, очень ценится.

+14

Это неблагоразумно назначить 'list', так как это встроенный. –

ответ

156

Самый простой способ сделать это с пониманием списка:

[s + mystring for s in mylist] 

Обратите внимание, что я избегал использовать встроенные имена, как list, потому что тени или скрывает встроенные имена, которые очень не хорошо.

Кроме того, если вы на самом деле не нужен список, но просто нужен итератор, выражение генератора может быть более эффективным (хотя это не вероятно делом в коротких списках):

(s + mystring for s in mylist) 

Это очень мощный, гибкий и лаконичный. Каждый хороший программист на Python должен научиться владеть ими.

+7

Или геникс, если вы хотите его лениво '(s + mystring для s в mylist)' –

+0

Это определенно сделал трюк, большое спасибо, все еще обнимая голову вокруг понимания списка, если вы знаете хороший учебник по нему. перед каждым элементом в списке есть u ', это для unicode? – Kevin

+0

@Kevin, да, 'u''' указывает строку Unicode. –

0
list2 = ['%sbar' % (x,) for x in list] 

И не следует использовать list в качестве наименования; он затеняет встроенный тип.

+0

Почему ''% sbar '% (x,) 'вместо' '% sbar' % x'? Почему бы не 'x + 'bar''? –

+1

Второе не получится, если x окажется кортежем. Очевидно, вы * планируете *, чтобы каждый элемент был строкой, но иногда все идет не так. Разница между первой и третьей - это в основном вкус, если только вы не получите строку из внешнего источника. –

+2

'raise exception'! = 'Fail'. Если у вас неправильный тип данных, у вас есть * уже * сбой. В моем предпочтительном выражении возникает исключение, указывающее на ошибку; ваше предпочтительное выражение молча производит мусор. Вкус: медленные выражения в стиле барокко мне не нравятся. –

0
new_list = [word_in_list + end_string for word_in_list in old_list] 

Использование имен, таких как «список» для ваших имен переменных, плохо, поскольку оно будет перезаписывать/переопределять встроенные функции.

14
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'] 
2

Я гавань нашел способ прокомментировать ответы до сих пор. Так вот оно. Я поддерживаю ответ Игнасио Васкес-Абрамса list2 = ['%sbar' % x for x in list].

Другие ответы с [string + "bar" for string in list] будут работать в большинстве случаев, но если вы примете более общее решение для простейшего случая - IMHO - следуя принципам проектирования Python. Должен быть предпочтительно один очевидный способ сделать это. %sbar работает все время.

+0

StackOverflow ограничивает комментирование других сообщений, пока вы не достигнете 50 пунктов. – Ponkadoodle

+1

@jeffjose: Ответ Игнасио был фактически 'list2 = ['% sbar'% (x,) для x в списке]'. Пожалуйста, дайте примеры, где x относится к строке, а ''% sbar '% x' "работает" и 'x +' bar'' не делает. –

+1

Исходный вопрос задал две строки. 's1 + s2' всегда будет работать (и наиболее эффективно) в этом случае. – gahooa

1

map кажется подходящим инструментом для работы для меня.

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

См this section на функциональных инструментов программирования для большего количества примеров map.

0

вы можете использовать лямбда внутри карты в python. написал генератор серых кодов. https://github.com/rdm750/rdm750.github.io/blob/master/python/gray_code_generator.py # коды здесь идут «»» битого код п-1, с 0 предварёнными к каждому слову, а затем битовый код п-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)) 
1

Запуск следующего эксперимента по вещий путь:

[s + mystring for s in mylist] 

, кажется, ~ 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 
Смежные вопросы