if/else in een lijstbegrip

Hoe kan ik het volgende doen in Python?

row = [unicode(x.strip()) for x in row if x is not None else '']

In wezen:

  1. vervang alle Nones door lege strings, en dan
  2. een functie uitvoeren.

Antwoord 1, autoriteit 100%

Dat kun je helemaal doen. Het is gewoon een bestelprobleem:

[unicode(x.strip()) if x is not None else '' for x in row]

Over het algemeen

[f(x) if condition else g(x) for x in sequence]

En, alleen voor lijstbegrippen met if-voorwaarden,

[f(x) for x in sequence if condition]

Merk op dat dit eigenlijk een andere taalconstructie gebruikt, een voorwaardelijke expressie, dat zelf geen deel uitmaakt van de begripsyntaxis, terwijl de if na de for…in deel uitmaakt van lijstbegrippen en wordt gebruikt om filter elementen uit de bron itereerbaar.


Voorwaardelijke expressies kunnen worden gebruikt in allerlei situaties waarin u wilt kiezen tussen twee expressiewaarden op basis van een voorwaarde. Dit doet hetzelfde als de ternaire operator ?: die in andere talen bestaat. Bijvoorbeeld:

value = 123
print(value, 'is', 'even' if value % 2 == 0 else 'odd')

Antwoord 2, autoriteit 3%

Het specifieke probleem is al opgelost in eerdere antwoorden, dus ik zal ingaan op het algemene idee van het gebruik van conditionals in lijstbegrippen.

Hier is een voorbeeld dat laat zien hoe conditionals kunnen worden geschreven in een lijstbegrip:

X = [1.5, 2.3, 4.4, 5.4, 'n', 1.5, 5.1, 'a']     # Original list
# Extract non-strings from X to new list
X_non_str = [el for el in X if not isinstance(el, str)]  # When using only 'if', put 'for' in the beginning
# Change all strings in X to 'b', preserve everything else as is
X_str_changed = ['b' if isinstance(el, str) else el for el in X]  # When using 'if' and 'else', put 'for' in the end

Merk op dat in het eerste lijstbegrip voor X_non_str de volgorde is:

uitdrukking voor item in iterable als staat

en in het laatste overzicht van de lijst voor X_str_changed is de volgorde:

expression1 if condition else expression2 voor item in itereerbaar

Ik vind het altijd moeilijk om te onthouden dat expression1 vóór if moet komen en expression2 na else. Mijn hoofd wil dat beide voor of na zijn.

Ik denk dat het zo is ontworpen omdat het lijkt op normale taal, b.v. “Ik wil binnen blijven als het regent, anders wil ik naar buiten”

In gewoon Engels kunnen de twee soorten lijstbegrippen die hierboven worden genoemd worden weergegeven als:

Met alleen if:

extract_apple voor apple in apple_box als apple_is_ripe

en met if/else

mark_apple if apple_is_ripe else leave_it_unmarked voor appel in apple_box


Antwoord 3, autoriteit 2%

Enkele reis:

def change(f):
    if f is None:
        return unicode(f.strip())
    else:
        return ''
row = [change(x) for x in row]

Hoewel je dan hebt:

row = map(change, row)

Of je kunt een lambda inline gebruiken.


Antwoord 4, autoriteit 2%

Hier is nog een illustratief voorbeeld:

>>> print(", ".join(["ha" if i else "Ha" for i in range(3)]) + "!")
Ha, ha, ha!

Het maakt gebruik van het feit dat if i evalueert naar False voor 0 en naar True voor alle andere waarden gegenereerd door de functie range(). Daarom wordt het begrip van de lijst als volgt geëvalueerd:

>>> ["ha" if i else "Ha" for i in range(3)]
['Ha', 'ha', 'ha']

Antwoord 5

De andere oplossingen zijn geweldig voor een enkele if / else constructie. Echter, ternaire uitspraken binnen lijstbegrippen zijn aantoonbaar moeilijk te lezen.

Het gebruik van een functie bevordert de leesbaarheid, maar een dergelijke oplossing is moeilijk uit te breiden of aan te passen in een workflow waar de mapping een invoer is. Een woordenboek kan deze zorgen wegnemen:

row = [None, 'This', 'is', 'a', 'filler', 'test', 'string', None]
d = {None: '', 'filler': 'manipulated'}
res = [d.get(x, x) for x in row]
print(res)
['', 'This', 'is', 'a', 'manipulated', 'test', 'string', '']

Antwoord 6

Het heeft te maken met hoe het begrip van de lijst wordt uitgevoerd.

Houd rekening met het volgende:

[ expression for item in list if conditional ]

Is gelijk aan:

for item in list:
    if conditional:
        expression

Waar de expression een iets andere indeling heeft (denk aan het wisselen van onderwerp en werkwoordvolgorde in een zin).

Daarom doet uw code [x+1 for x in l if x >= 45] dit:

for x in l:
    if x >= 45:
        x+1

Deze code [x+1 if x >= 45 else x+5 for x in l] doet echter dit (na het herschikken van de expression):

for x in l:
    if x>=45: x+1
    else: x+5

Antwoord 7

Maak een lijst van items in een iterable

Het lijkt het beste om eerst alle mogelijke vormen te generaliseren in plaats van specifieke antwoorden op vragen te geven. Anders weet de lezer niet hoe het antwoord tot stand is gekomen. Hier zijn een paar algemene vormen die ik bedacht voordat ik hoofdpijn kreeg toen ik probeerde te beslissen of een laatste else’-clausule in de laatste vorm kon worden gebruikt.

[expression1(item)                                        for item in iterable]
[expression1(item) if conditional1                        for item in iterable]
[expression1(item) if conditional1 else expression2(item) for item in iterable]
[expression1(item) if conditional1 else expression2(item) for item in iterable if conditional2]

De waarde van item hoeft niet te worden gebruikt in een van de voorwaardelijke clausules. Een conditional3 kan worden gebruikt als een schakeloptie om al dan niet een waarde toe te voegen aan de uitvoerlijst.

Als u bijvoorbeeld een nieuwe lijst wilt maken die lege tekenreeksen of witruimtetekenreeksen uit de oorspronkelijke lijst met tekenreeksen elimineert:

newlist = [s for s in firstlist if s.strip()]

Antwoord 8

u kunt dit doen

row = [unicode(x.strip()) if x != None else '' for x in row]

Enige syntaxis voor het begrijpen van een lijst:

[item if condition else item for item in items]
[f(item) if condition else value for item in items]
[item if condition for item in items]
[value if condition else value1 if condition1 else value2]

Antwoord 9

Er is geen noodzaak voor ternaire if/then/else. Naar mijn mening vraagt ​​uw vraag om dit antwoord:

row = [unicode((x or '').strip()) for x in row]

Antwoord 10

U kunt voorwaardelijke logica combineren in een begrip:

 ps = PorterStemmer()
 stop_words_english = stopwords.words('english')
 best = sorted(word_scores.items(), key=lambda x: x[1], reverse=True)[:10000]
 bestwords = set([w for w, s in best])
 def best_word_feats(words):
   return dict([(word, True) for word in words if word in bestwords])
 # with stemmer
 def best_word_feats_stem(words):
   return dict([(ps.stem(word), True) for word in words if word in bestwords])
 # with stemmer and not stopwords
 def best_word_feats_stem_stop(words):
   return dict([(ps.stem(word), True) for word in words if word in bestwords and word not in stop_words_english])

Antwoord 11

# coding=utf-8
def my_function_get_list():
    my_list = [0, 1, 2, 3, 4, 5]
    # You may use map() to convert each item in the list to a string, 
    # and then join them to print my_list
    print("Affichage de my_list [{0}]".format(', '.join(map(str, my_list))))
    return my_list
my_result_list = [
   (
       number_in_my_list + 4,  # Condition is False : append number_in_my_list + 4 in my_result_list
       number_in_my_list * 2  # Condition is True : append number_in_my_list * 2 in my_result_list
   )
   [number_in_my_list % 2 == 0]  # [Condition] If the number in my list is even
   for number_in_my_list in my_function_get_list()  # For each number in my list
]
print("Affichage de my_result_list [{0}]".format(', '.join(map(str, my_result_list))))

(venv) $ python list_comp.py
Affiche van mijn_lijst [0, 1, 2, 3, 4, 5]
Affiche van my_result_list [0, 5, 4, 7, 8, 9]

Dus voor jou:
row = [('', unicode(x.strip()))[x is not None] for x in row]

LEAVE A REPLY

Please enter your comment!
Please enter your name here

seven + 19 =

Other episodes