从字符串列表中提取特定元素并创建新列表?

时间:2016-12-22 19:36:49

标签: python list

我是python的初学者。

这是我的问题。我有一个列表如下

lst = ['UGAGGUAGUAGGUUGUAUAGUU', 'CUAUGCAAUUUUCUACCUUACC', 'UCCCUGAGACCUCAAGUGUGA',
       'ACACCUGGGCUCUCCGGGUACC', 'CAUACUUCCUUACAUGCCCAUA', 'UGGAAUGUAAAGAAGUAUGUA',
       'CAUCAAAGCGGUGGUUGAUGUG', 'UAUCACAGCCAGCUUUGAUGUGC', 'AGGCAGUGUGGUUAGCUGGUUG',
       'ACGGCUACCUUCACUGCCACCC']

现在我需要从lst中的所有10个元素中提取第一个字母,然后将它们放入新列表中。类似的第二个字母,第三个字母等等,直到从所有十个元素中提取最后一个字母并将其附加到新列表。输出必须看起来像这样

new_lst = ['UCUACUCUAA', 'GUCCAGAAGC', 'AACAUGUUGG', 'GUCCAACCCG', 'GGUCCAAAAC',
           'UCGUUUACGU', 'AAAGUGAAUA', 'GAGGCUGGGC', 'UUAGCACCUC', 'AUCCUAGCGU', ..., 'C']

我试过这段代码:

new_lst = []
new_lst.append(''.join([x[i] for x in lst]))

上面的代码只打印new_list中的前10个元素,因为索引是0到9(我误解了索引的含义)。

然后我做了以下

final= []
for j in range(1,len(lst),1):
 new_lst = []
 for x in lst:
   c = len(x)
    for i in range(1,c,1):
       while (i<len(x)):
          new_lst.append(x[i])
       else:
          new_lst.append("")
 final.append([new_lst])
print final

当我执行此代码时,它会引发内存错误。我检查长度的原因是因为lst中的元素长度不同,当我使用不同的代码时,它会抛出错误IndexError: string index out of range

我首先想要剖析代码,所以我只使用了以下代码:

lst2 = []
for x in lst:
 c = len (x)
 print c
  for i in range(0,c,1):
    print i,
    print x[i],

我得到了以下输出:

22
0 U 1 G 2 A 3 G 4 G 5 U 6 A 7 G 8 U 9 A 10 G 11 G 12 U 13 U 14 G 15 U 16       A 17 U 18 A 19 G 20 U 21 U 22
0 C 1 U 2 A 3 U 4 G 5 C 6 A 7 A 8 U 9 U 10 U 11 U 12 C 13 U 14 A 15 C 16  C 17 U 18 U 19 A 20 C 21 C 21
0 U 1 C 2 C 3 C 4 U 5 G 6 A 7 G 8 A 9 C 10 C 11 U 12 C 13 A 14 A 15 G 16 U 17 G 18 U 19 G 20 A 22
0 A 1 C 2 A 3 C 4 C 5 U 6 G 7 G 8 G 9 C 10 U 11 C 12 U 13 C 14 C 15 G 16 G 17 G 18 U 19 A 20 C 21 C 22
0 C 1 A 2 U 3 A 4 C 5 U 6 U 7 C 8 C 9 U 10 U 11 A 12 C 13 A 14 U 15 G 16 C 17 C 18 C 19 A 20 U 21 A 21
0 U 1 G 2 G 3 A 4 A 5 U 6 G 7 U 8 A 9 A 10 A 11 G 12 A 13 A 14 G 15 U 16 A 17 U 18 G 19 U 20 A 22
0 C 1 A 2 U 3 C 4 A 5 A 6 A 7 G 8 C 9 G 10 G 11 U 12 G 13 G 14 U 15 U 16 G 17 A 18 U 19 G 20 U 21 G 23
0 U 1 A 2 U 3 C 4 A 5 C 6 A 7 G 8 C 9 C 10 A 11 G 12 C 13 U 14 U 15 U 16 G 17 A 18 U 19 G 20 U 21 G 22 C 22
0 A 1 G 2 G 3 C 4 A 5 G 6 U 7 G 8 U 9 G 10 G 11 U 12 U 13 A 14 G 15 C 16 U 17 G 18 G 19 U 20 U 21 G 22
0 A 1 C 2 G 3 G 4 C 5 U 6 A 7 C 8 C 9 U 10 U 11 C 12 A 13 C 14 U 15 G 16 C 17 C 18 A 19 C 20 C 21 C

如上所示,循环遍历第一个元素,但在从lst中的第一个元素中提取第一个字符后,它将转到第一个元素中的第二个字符。但我希望循环遍历列表lst中的第二个元素。此外,列表中的元素长度不等,所以想知道是否有办法避免IndexError: string index out of range

我想我错过了什么,可能太傻了。抱歉天真。如果你能提出不同的方法来完成这项工作,那就太棒了。我在线查看了使用numpy模块中的数组,但有没有办法在没有numpy的情况下执行此操作?

2 个答案:

答案 0 :(得分:3)

您可以使用itertools.zip_longest

import itertools
[''.join(chars) for chars in itertools.zip_longest(*lst,fillvalue = '')]

输出:

['UCUACUCUAA', 'GUCCAGAAGC', 'AACAUGUUGG', 'GUCCAACCCG', 'GGUCCAAAAC', 'UCGUUUACGU', 'AAAGUGAAUA', 'GAGGCUGGGC', 'UUAGCACCUC', 'AUCCUAGCGU', 'GUCUUAGAGU', 'GUUCAGUGUC', 'UCCUCAGCUA', 'UUACAAGUAC', 'GAACUGUUGU', 'UCGGGUUUCG', 'ACUGCAGGUC', 'UUGGCUAAGC', 'AUUUCGUUGA', 'GAGAAUGGUC', 'UCACUAUUUC', 'UCCAGGGC', 'C']

内置的zip()以及Python 3中的itertools方法zip_longest()(或者,在Python 2中,itertools方法izip()和当您想要并行处理两个或更多个迭代(例如列表,字符串或生成器)时,izip_longest())是首选工具。要查看zip()zip_longest()之间的区别,请考虑以下事项:

for chars in zip('ABCD','EFG','HI'):
    print(chars)
print('')
for chars in itertools.zip_longest('ABCD','EFG','HI',fillvalue = ''):
    print(chars)

输出:

('A', 'E', 'H')
('B', 'F', 'I')

('A', 'E', 'H')
('B', 'F', 'I')
('C', 'G', '')
('D', '', '')

产生的第一个元组是第一个元素的元组,第二个元组产生的是第二个元素的元组,等等。zip(或izip)在第一个元素出现时立即停止累。在这种情况下,它不能返回每个字符串中第三个字符的元组,因为zip的第三个输入缺少第三个字符。 zip_longest()(或izip_longest())允许fillvalue在更短的迭代中取代丢失的项目。在这里,我使用了空字符串,因为当元组由''连接时,它会消失。

在上面的代码中,我将3个字符串硬连线到zip_longest()。对于您的问题,您必须明确输入10个输入,这在极端情况下会很乏味,或者使用解包操作符 *。如果我有一个清单:

strings = ['ABCD','EFG', 'HI']

然后

for char in itertools.zip_longest(*strings, fillvalue = ''):

等同于

for chars in itertools.zip_longest('ABCD','EFG','HI',fillvalue = ''):

答案 1 :(得分:1)

您需要遍历最长字符串的索引:

lst = ['UGAGGUAGUAGGUUGUAUAGUU', 'CUAUGCAAUUUUCUACCUUACC',
       'UCCCUGAGACCUCAAGUGUGA', 'ACACCUGGGCUCUCCGGGUACC',
       'CAUACUUCCUUACAUGCCCAUA', 'UGGAAUGUAAAGAAGUAUGUA', 
       'CAUCAAAGCGGUGGUUGAUGUG', 'UAUCACAGCCAGCUUUGAUGUGC',
       'AGGCAGUGUGGUUAGCUGGUUG', 'ACGGCUACCUUCACUGCCACCC']

max_len = max(len(x) for x in lst) # length of the longest string
new_lst = [ ''.join(x[i] for x in lst if i < len(x)) for i in range(max_len)]