简体   繁体   中英

How do I change a variable in each iteration in a list comprehension?

So I wrote this function that takes a string and removes consecutive duplicate words.

def remove_consecutive_duplicates(s):
    previous_string = None
    li = []
    for i in s.split():
        if i != previous_string:
            li.append(i)
            previous_string = i
    return " ".join(li)

input: 'alpha beta beta gamma gamma gamma delta alpha beta beta gamma gamma gamma delta'

output: 'alpha beta gamma delta alpha beta gamma delta'

But my question is how do I add previous_string = i it in a list comprehension? Is this even possible?

Normally if there wasn't any previous_string = i then I'd probably do it like this:

def remove_consecutive_duplicates(s):
    previous_string = None
    return " ".join([i for i in s.split() if i != previous_string])

But I have no clue how or where do I add previous_string = i in this case.

Since Python 3.8 you could use assignment expression :=

def remove_consecutive_duplicates(s):
    prev = None
    return " ".join([prev := i for i in s.split() if i != prev])

Solution

One-line solution: this should work for python 3.6+

[x for x, y in zip(values, values[1:] + [None]) if x!=y]

Example

## Dummy data
s = 'alpha beta beta gamma gamma gamma delta alpha beta beta gamma gamma gamma delta'
# create a list
values = s.split()

## Get required output
[x for x, y in zip(values, values[1:] + [None]) if x!=y]
# ['alpha', 'beta', 'gamma', 'delta', 'alpha', 'beta', 'gamma', 'delta']

It might get a bit unreadable at some point but if you're sure you want to do it in a list comprehension:

def remove_consecutive_duplicates(s):
    words = s.split()
    return " ".join([words[0]]+[words[i+1] for i in range(len(words)-1) if words[i+1] != words[i]])

test = remove_consecutive_duplicates('alpha beta beta gamma gamma gamma delta alpha beta beta gamma gamma gamma delta')
print(test)

you can use 'groupby' function from itertools together with list comprehension as follow:

from itertools import groupby  
def remove_consecutive_duplicates(s):
    return " ".join([word[0] for word in groupby(s.split(" "))])

Its readable enough.

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