简体   繁体   中英

Joining strings with a list of lists if they meet a specific condition

I have this list of lists:

x = [["hello", 1, "pacific", 'M','F','W'], ["yes", 4, 5, "turn", 'S', 'F', 'Su']]

I would like to join specific items in the list: 'M','F','W','S','Su'

So if any of these items exist in the list they should be joined together resulting in:

x = [["hello", 1, "pacific", 'M,F,W'], ["yes", 4, 5, "turn", 'S,F,Su']]

My Current attempt looks like this:

x = [["hello", 1, "pacific", 'M','F','W'], ["yes", 4, 5, "turn", 'S', 'F', 'Su']]

z = []

for item in x: 

    for y in item:

        if y == 'M' or y == 'F' or y =='W' or y == 'S' or y =='Su':

            item.index(y)

            z.append((item.index(y)))

        else:
            pass

x[min(z):max(z)+1] = [','.join(item[min(z):max(z)+1])]

print(x)

I thought I could grab the positions of the specific strings I want in the list and then join them using min and max.

My code returns:

[['hello', 1, 'pacific', 'M', 'F', 'W'], ['yes', 4, 5, 'turn', 'S', 'F', 'Su'], 'turn,S,F']

Any help is very much appreciated!

Try this one liner list comprehension:

[[i for i in sublist if i not in l] + [','.join([i for i in sublist if i in l])] for sublist in x]

Output:

[['hello', 1, 'drugs', 'M,F,W'], ['yes', 4, 5, 'turn', 'S,F,Su']]

Full code:

x = [["hello", 1, "drugs", 'M','F','W'], ["yes", 4, 5, "turn", 'S', 'F', 'Su']]
l = ['M', 'F', 'W', 'S', 'Su']
print([[i for i in sublist if i not in l] + [','.join([i for i in sublist if i in l])] for sublist in x])

This just loops through the list and in each sublist it extracts all strings that are not in the l list, and adds a value as a last element which is a string with the strings in the sublist which are also in the l list joined and separated by commas.

Edit:

Due to knowing that the specific items are not going to be always at the end, you could try using itertools.takewhile and itertools.dropwhile .

I modified your list a bit (moving location of the specific items), to prove that my code works:

from itertools import takewhile, dropwhile
x = [["hello", 1, 'M','F','W', "drugs"], ["yes", 4, 5, 'S', 'F', 'Su', "turn"]]
l = ['M', 'F', 'W', 'S', 'Su']
newlist = []
for sublist in x:
    b = list(takewhile(lambda x: x not in l, sublist))
    newlist.append(b + [','.join([i for i in sublist if i in l])] + list(dropwhile(lambda x: x in l, sublist[len(b):])))
print(newlist)

Output:

[['hello', 1, 'M,F,W', 'drugs'], ['yes', 4, 5, 'S,F,Su', 'turn']]

It works as expected.

你可以试试set

[[*set(i).difference([ 'M','F','W','S','Su']), ','.join(set(i).intersection([ 'M','F','W','S','Su']))] for i in x]
[['hello', 1, 'pacific', 'F,W,M'], ['yes', 4, 5, 'turn', 'F,S,Su']]

You can use itertools.groupby to group together consecutive items that belong to one of the key items you're looking for so you can join them into a comma-delimited string while leaving the other items separate:

from itertools import groupby

x = [
    ["hello", 1, 'M', 'F', 'W', "pacific", "S", "Su", "no"],
    ["yes", 4, 5, "turn", 'S', 'F', 'Su']
]
keys = {'M', 'F', 'W', 'S', 'Su'}
print([
    [
        i
        for k, g in groupby(lst, keys.__contains__)
        for i in ([','.join(g)] if k else g)
    ] for lst in x
])

This outputs:

[['hello', 1, 'M,F,W', 'pacific', 'S,Su', 'no'], ['yes', 4, 5, 'turn', 'S,F,Su']]

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