简体   繁体   中英

How to create tuples from a single list with alpha-numeric chacters?

I have the following list with 2 elements:

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

I need to make a list or zip file such that each alphabet corresponds to its number further in the list. For example in list[0] the list/zip should read

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

Can I make a list of such lists/zips that stores the corresponding vales for list[0], list[1],...list[n]?

Note: The alphabets can only be A,G,C or T, and the numbers can take anyvalue

Edit 1: Previously, I thought I could use a dictionary. But several members pointed out that this cannot be done. So I just want to make a list or zip or anything else recommended to pair the Alphabet element to its corresponding number.

Use tuples splitting once to get the pairs, then split the second element of each pair, zip together:

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]

Which would give you:

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

Of using a for loop with list.append:

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))

If you want to convert any letter to Z where the digit is < 10, you just need another loop where we check the digit in each pairing:

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)

Which would give you:

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

To break it into a regular loop:

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) < 10 else (c, i) for c, i in zip(a, b.split())] sets the letter to Z if the corresponding digit i is < 10 or else we just leave the letter as is.

if you want to get back to the original pairs after you just need to transpose with 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(*...) will give you the original elements back into a tuple of their own, we then just need to join the strings back together. If you wanted to get back to the total original state you could just join again:

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

If you consider using tuples to pair the items, then this works:

>>> 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] : An initial split on the string.

  2. zip(sub[0], sub[1:])) : Zip lists of alphabets and list of numbers

Iterate through list > iterate through items (alpha numeric) of the list and construct list of characters and numbers > and then construct list of tuple.

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

This code would work, assuming the elements in the list are correctly formed. This means the number of letters and numbers must match!

And it will overwrite the value if the key already exists.

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

This modified one will check if the key exists and add it to a list with that key:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM