0

Please consider this snippet:

>>> i = ["", 1, 2]
>>> all([x for x in i])
False

What would be Pythonic way to make this snippet return True even if item in iterable is empty string?

Standard restrictions should apply - if item is None or False etc, it should return False as expected.

2
  • Do you mean you want the snippet to return True unless at least one item is falsey, but count an empty string as truthy? I.e. follow Python's rules on what is counted True and False except for an empty string? Commented Aug 28, 2016 at 18:44
  • Yes, that's correct Commented Aug 28, 2016 at 18:44

4 Answers 4

2
>>> lst = ["", 1, 2]
>>> 
>>> all(True if i=='' else i for i in lst)
True

If you want True if there is at least one item that evaluates to True use any().

>>> any(lst)
True

Note that in general any() and all() accept iterable argument and you don't need to loop over them.

Sign up to request clarification or add additional context in comments.

4 Comments

As both your and @two-bit-alchemist's answers are correct, I'll accept his answer because he has much less score points compared to you. I hope you don't mind. Thanks
@vlad First off, The answers are different secondly you always should consider to accepting the correct answer, I don't think this imaginary points gotta do something for us :-D
Ok, thanks for your reply. Can you point to single scenario where your snippet will give different result then @two-bit-alchemist's? Or what makes your snippet different? As a side note: my points are not imaginary, but driven from common human ethics, something lot of people unfortunately lack.
@vlad It's correct in this case but actually it denies all the strings. For example if you want to get False for a string like "''" or another ones you can't use that answer. In that case you can use all(True if i not it {set of special strings} else i for i in lst)
2

This option looks nice to me.

all(x or x=="" for x in i)

Comments

1
all([x for x in i if not isinstance(x, str)])

The only falsy string is the empty string, so if you don't want to test for it, then filter out the strings.

7 Comments

A nitpick: [] are redundant.
all(x for x in filter(None, i)) -slightly cleaner if you only have to worry about empty strings
@reticentroot No, the default filter (None) removes all falsy, which would get rid of False and None as well.
Oh your right, totally forget about that. So if the OP needs to filter those items out that's still cleaner than an isinstance, though an isinstance is more flexible. :-) thanks for the reminder.
@bereal I can't find my handy link comparing the behavior, but it basically depends. Generators consume less memory but must be remade each time they are used. List comprehensions generate all the values but are more efficient for reuse. It's not redundant; it's different. Which is better depends on context.
|
-1

You can use all, for instance:

tests = [
    [None, False, "", 1, 2],
    ["", 1, 2],
    [1, 2],
    []
]

for i in tests:
    print i
    print all(filter(lambda x: x != '', i))
    print all(True if x == '' else x for x in i)
    print '-' * 80

1 Comment

Your first solution fails the requirement of catching other falsy values like None or False because it filters them out. Your third solution fails because it bails after it finds one truthy value, which is not what is wanted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.