【问题标题】:How to create tuples from a single list with alpha-numeric chacters?如何从带有字母数字字符的单个列表创建元组?
【发布时间】:2017-01-19 09:13:51
【问题描述】:

我有以下包含 2 个元素的列表:

['AGCTT 6 6 35 25 10', 'AGGGT 7 7 28 29 2']

我需要制作一个列表或 zip 文件,以便每个字母对应于列表中进一步的编号。例如,在 list[0] 中,list/zip 应该是

{"A":"6", "G":"6", "C":"35","T":"25","T":"10"}

我可以列出这样的列表/zip 来存储 list[0]、list[1]、...list[n] 的相应值吗?

注意:字母只能是A、G、C或T,数字可以取任意值

编辑 1:以前,我认为我可以使用字典。但有几位委员指出,这是做不到的。所以我只想制作一个列表或 zip 或任何其他建议将 Alphabet 元素与其对应的数字配对。

【问题讨论】:

  • 第二个字符串中有3个Gs,你会如何在字典中处理这个?
  • {"A":"6", "G":"6", "C":"35","T":"25","T":"10"} 有多个T 键;无效
  • 您不能有一个字典,其中多个键相同(“T”)。您可以让键“T”有多个值
  • 正如已经指出的那样,您不能拥有重复密钥,因此您的预期输出是不可能的。您需要编辑问题来解决这个问题。
  • @MosesKoledoye 和大家:感谢您指出。我已经修改了问题

标签: python list dictionary zip tuples


【解决方案1】:

使用元组拆分一次得到对,然后将每对的第二个元素拆分,zip在一起:

l  =['AGCTT 6 6 35 25 10', 'AGGGT 7 7 28 29 2']

pairs =  [zip(a,b.split()) for a,b in (sub.split(None,1) for sub in l]

这会给你:

[[('A', '6'), ('G', '6'), ('C', '35'), ('T', '25'), ('T', '10')], [('A', '7'), ('G', '7'), ('G', '28'), ('G', '29'), ('T', '2')]]

list.append 中使用 for 循环:

l  = ['AGCTT 6 6 35 25 10', 'AGGGT 7 7 28 29 2']
out = []
for a,b in (sub.split(None,1) for sub in l ):
    out.append(zip(a,b))

如果您想将任何字母转换为Z,其中数字小于 10,您只需要另一个循环,我们检查每个配对中的数字:

pairs = [[("Z", i ) if int(i) < 10 else (c, i) for c,i in zip(a, b.split())] 
         for a,b in (sub.split(None, 1) for sub in l)]
print(pairs)

这会给你:

[[('Z', '6'), ('Z', '6'), ('C', '35'), ('T', '25'), ('T', '10')], [('Z', '7'), ('Z', '7'), ('G', '28'), ('G', '29'), ('Z', '2')]]

要将其分解为常规循环:

pairs = []
for a, b in (sub.split(None, 1) for sub in l):
    pairs.append([("Z", i) if int(i) < 10 else (c, i) for c, i in zip(a, b.split())])
print(pairs)

[("Z", i) if int(i) &lt; 10 else (c, i) for c, i in zip(a, b.split())] 如果对应的数字 i&lt; 10,则将字母设置为 Z,否则我们将保持原样。

如果你想在transposetranspose zip 之后恢复原来的对:

In [13]: l = ['AGCTT 6 6 35 25 10', 'AGGGT 7 7 28 29 2']

In [14]: pairs = [[("Z", i) if int(i) < 10 else (c, i) for c, i in zip(a, b.split())] for a, b in
   ....:          (sub.split(None, 1) for sub in l)]

In [15]: pairs
Out[15]: 
[[('Z', '6'), ('Z', '6'), ('C', '35'), ('T', '25'), ('T', '10')],
 [('Z', '7'), ('Z', '7'), ('G', '28'), ('G', '29'), ('Z', '2')]]

In [16]: unzipped = [["".join(a), " ".join(b)] for a, b in (zip(*tup) for tup in pairs)]

In [17]: unzipped
Out[17]: [['ZZCTT', '6 6 35 25 10'], ['ZZGGZ', '7 7 28 29 2']]

zip(*...) 会将原始元素返回到它们自己的元组中,然后我们只需要将字符串重新连接在一起。如果你想回到原来的状态,你可以再次加入:

In[18][ " ".join(["".join(a), " ".join(b)]) for a, b in (zip(*tup) for tup in pairs) ]
Out[19]: ['ZZCTT 6 6 35 25 10', 'ZZGGZ 7 7 28 29 2']

【讨论】:

  • 谢谢。但我需要将列表 AGCTT 和 AGGGT(以及大约 10 个其他元素)中的两个元素分开存储。另外,在这种方法中,我可以分别访问数字和字母吗?例如,对于值小于 10 的字母,我想将字母替换为“Z”
  • 分开存放是什么意思?如果这就是您的意思,我进行了编辑以删除展平。
  • 我需要:[[('A', '6'), ('G', '6'), ('C', '35'), ('T', '25 '), ('T', '10')], [('A', '7'), ('G', '7'), ('G', '28'), ('G', '29'), ('T', '2')]]
  • 而且我应该能够编写一个进一步的代码来说明值
  • @Ash1234,这就是代码现在在做什么,所以你想让T变成Z?
【解决方案2】:

如果您考虑使用元组对项目进行配对,则可以这样做:

>>> from pprint import pprint
>>> lst = ['AGCTT 6 6 35 25 10', 'AGGGT 7 7 28 29 2']
>>> new_lst = [list(zip(sub[0], sub[1:])) for sub in [i.split() for i in lst]]
>>> pprint(new_lst)
[[('A', '6'), ('G', '6'), ('C', '35'), ('T', '25'), ('T', '10')],
 [('A', '7'), ('G', '7'), ('G', '28'), ('G', '29'), ('T', '2')]]
  1. [i.split() for i in lst]:对字符串进行初始拆分。

  2. zip(sub[0], sub[1:])):字母压缩列表和数字列表

【讨论】:

  • 非常感谢。但这可以作为一个列表工作吗?例如,我应该能够为值
  • @PadraicCunningham 我的错。谢谢!
【解决方案3】:

遍历列表 > 遍历列表的项目(字母数字)并构造字符和数字列表 > 然后构造元组列表。

alphanum = ['AGCTT 6 6 35 25 10', 'AGGGT 7 7 28 29 2']
list_of_tuple = []

for s in alphanum:
   ints = []
   chars = []
   for i in s.split():
      if i.isdigit():
         ints.append(i)
      else:
         chars.append(i)

   new_tuple = []
   for (n, item) in enumerate(list(chars[0])):
       new_tuple.append((item, ints[n]))
   list_of_tuple.append(new_tuple)

print list_of_tuple

【讨论】:

    【解决方案4】:

    假设列表中的元素格式正确,此代码将起作用。 这意味着字母和数字的数量必须匹配!

    如果键已经存在,它将覆盖该值。

    list = ['AGCTT 6 6 35 25 10', 'AGGGT 7 7 28 29 2']
    dictionary = {}
    
    for line in list:
        split_line = line.split()
        letters = split_line[0]
        iterator = 1
        for letter in letters:
            dictionary[letter] = split_line[iterator]
            iterator += 1
    
    print dictionary
    

    这个修改后的将检查密钥是否存在并将其添加到具有该密钥的列表中:

    list = ['AGCTT 6 6 35 25 10', 'AGGGT 7 7 28 29 2']
    dictionary = {}
    
    for line in list:
        split_line = line.split()
        letters = split_line[0]
        iterator = 1
        for letter in letters:
            if letter in dictionary.keys():
                dictionary[letter].append(split_line[iterator])
            else:
                dictionary[letter] = [split_line[iterator]]
    
            iterator += 1
    
    print dictionary
    

    【讨论】:

    • 这不应该被否决。最初的问题一开始就有缺陷,而且无法解决。 OP 想要创建一个字典,其中一个键映射到 2 个值。
    • 谢谢,如果您认为这是用户真正想要的,您可以投票。
    猜你喜欢
    • 2017-04-17
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多