简体   繁体   中英

Update values in list of list of tuples

I needed to go through all the tuples and change the value of the second item of the tuple to its 2 first letters after the first "/" (AA/BB/CC would become AA)

For the list

[[("AA","AA/BB/AA"),("QQ","AB/AA")],[("CC","CC/SS/AA"),("QQ","CC/CC")],...]

would return this:

[[("AA","AA"),("QQ","AB")],[("CC","CC"),("QQ","CC")],...]

I know how to do it with loops and changing from tupples to lists and to tuples back... but is there a way to do it in a shorter way?

Thanks in advance for nay help!!

For doing a single replacement on a string works, you can use str.split to split the string by slashes. str.split will return a list of the substrings it extracted from the string. As you are only interested in the substring before the first slash, you just need to get the first element of the result list. You can further use the maxsplit parameter to restrict str.split from splitting the string more than once (to make it stop processing the string earlier).

>>> 'AA/BB/CC'.split('/')
['AA', 'BB', 'CC']
>>> 'AA/BB/CC'.split('/', 1)
['AA', 'BB/CC']
>>> 'AA/BB/CC'.split('/', 1)[0]
'AA'

Now to perform the replacement across the list you have two choices: Either you replace the list in place , updating each element if necessary, or you create a new list where you apply the transformation on the fly. Note that you will always have to create new tuples though as they are immutable. As it's generally a preferred way to solve things, I'm only showing you how to do the second way using list comprehension. But if you wanted to replace the elements in place, you would just have to loop through the list and update the list items.

>>> lst = [[("AA", "AA/BB/AA"), ("QQ", "AB/AA")], [("CC", "CC/SS/AA"), ("QQ", "CC/CC")]]
>>> [[(a, b.split('/', 1)[0]) for a, b in x] for x in lst]
[[('AA', 'AA'), ('QQ', 'AB')], [('CC', 'CC'), ('QQ', 'CC')]]

A list comprehension in general looks like this:

[t(x) for x in sequence]

For every element x in the sequence it will apply the transformation t to the element x and put that as an element in the list. So [x for x in lst] would just return an identical list t would be the identify function.

The element x can also be an unpacked tuple. If the elements in the source list are two-element tuples, you can use [t(a, b) for a, b in lst] to unpack the elements from the tuple, apply the transformation and put that into the result list.

In your case, we want to unpack the tuple, so we can work on the second element only. But we also want to keep it a tuple, so we put the result in a tuple again: [(a, t(b)) for a, b in x] . In this case, the transformation t would be the splitting I showed earlier.

Now because your list is actually not a list of tuples, but a list of lists of tuples , we have to nest two list comprehensions. Similar to above [[y for y in x] for x in lst] would reproduce a list of lists. Now as the inner list is a list of tuples, we can perform the transformation on the tuples there and put everything together.

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