标签云

微信群

扫码加入我们

WeChat QR Code

For example, if passed the following:a = []How do I check to see if a is empty?


Playing devil's advocate. I don't understand why this idiom is considered pythonic. 'Explicit is better then implicit', correct? This check doesn't seem very explicit about what is is checking.

2019年08月20日11分27秒

JamesMcMahon - it's a trade-off between explicitness and type flexibility.generally, "being explicit" means not doing "magical" things.on the other hand, "duck typing" means working with more general interfaces, rather than explicitly checking for types.so something like if a == [] is forcing a particular type (() == [] is False).here, general consensus seems to be that duck typing wins out (in effect, saying that __nonzero__ is the interface for testing emptiness docs.python.org/reference/datamodel.html#object.__nonzero__)

2019年08月19日11分27秒

This method doesn't work on numpy arrays.. so I think if len(a) == 0 is preferable both in terms of "duck typing" and implicitness.

2019年08月19日11分27秒

The canonical way of knowing if an array in C is empty is by dereferencing the first element and seeing if it is null, assuming an array that is nul-terminated. Otherwise, comparing its length to zero is utterly inefficient if the array is of a significant size. Also, typically, you would not allocate memory for an empty array (pointer remains null), so it makes no sense to attempt to get its length. I am not saying that len(a) == 0 is not a good way of doing it, it just does not scream 'C' to me when I see it.

2019年08月19日11分27秒

sleblanc I've never seen a null terminated array in c outside of implementing a string, the common case is not to null terminate. "comparing its length to zero is utterly inefficient" is incorrect, there is no c implementation in existence where this would cost more than a couple cycles. Comparing the length of an array to 0 to determine emptiness is standard practice in c and almost all c influenced languages (c++, java, c#, etc).

2019年08月19日11分27秒

The second way seems better if you wish to signal that seq is expected to be some sort of list-like object.

2019年08月19日11分27秒

BallpointBen which, Pythonism advocates would say, should be implicit in the way the variable is named, as much as possible

2019年08月19日11分27秒

BallpointBen try using Python's type hinting for signaling what a variable should be. It was introduced in 3.5.

2019年08月19日11分27秒

numpy broke this idiom... seq = numpy.array([1,2,3]) followed by if not seq raises an exception "ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"

2019年08月19日11分27秒

Checking if the length of a list is equal to zero, rather than just checking if the list is false, is ugly and unpythonic. Anyone familiar with Python will not think li is a bool at all, and wont care. If it's important, you should add a comment, not more code.

2019年08月19日11分27秒

This seems like an unnecessarily precise test, which is often slower and is always less readable IMHO.Instead of checking the size of something empty, why not just check if it's empty?

2019年08月19日11分27秒

Anyway, the reason this is bad (and that violating idioms in a language with strong idioms like Python is bad in general) is that it signals to the reader that you're specifically checking the length for some reason (e.g., because you want None or 0 to raise an exception rather than passing). So, when you do it for no reason, that's misleading—and it also means that when your code does need to make the distinction, the distinction is invisible because you've "cried wolf" all over the rest of the source.

2019年08月19日11分27秒

I think this is just needlessly lengthening the code.Otherwise, why not be even more "explicit" with if bool(len(li) == 0) is True:?

2019年08月19日11分27秒

Jabba it will be O(1) in many cases (those where you work with the built-in data types), but you just can't rely on that. You might be working with a custom data type that doesn't have this property. You might also decide to add this custom data type later, after you already wrote this code.

2019年08月19日11分27秒

It's worth noting that this isn't a flaw in Python, but rather an intentional break of contract by numpy - numpy is a library with a very specific use case, and it has a different 'natural' definition of what truthiness on an array is to the Python standard for containers. It makes sense to optimise for that case, in the way that pathlib uses / to concatenate paths instead of + - it's non-standard, but makes sense in context.

2019年08月19日11分27秒

Agreed.My point is just that it's important to remember that numpy has made the choice to break duck typing for both the very common if x and len(x) idioms -- and sometimes that breakage can be very hard to detect and debug.

2019年08月19日11分27秒

I don't know, for me, if a method called len(x) doesn't return the array length because assumptions, it's name is bad designed.

2019年08月19日11分27秒

This question has nothing to do with numpy arrays

2019年08月19日11分27秒

ppperry Yes, the original question was not about Numpy arrays, but when working with those and possibly duck typed arguments, this question becomes very relevant.

2019年08月19日11分27秒

The thing is, check if the list is empty is quite important, at least for me. Have you considered if there's some script inside <rest of code> that might use the result from the for loop? Or directly use some values in a?Indeed, if the script is designed to run with strictly controlled input, the check might be a little unnecessary. But in most cases, the input varies, and have a check is usually better.

2019年08月19日11分27秒

This is a good point in most cases

2019年08月19日11分27秒

Respectfully, no.What I considered was someone who didn’t know enough about Python to know that “if <list>:” was the correct answer, asked how to check for an empty list.Then I notice a LOT of answers that offered differing opinions, but none seemed to address the original need.That is what I tried to do with my answer—have them examine the need before continuing.I believe I suggested as much in my answer, explicitly.

2019年08月19日11分27秒

AmarthGûl - How might one get the results from the for loop to the script inside <rest of code> to be processed?In a list, perhaps? Or maybe a dict?If so, the same logic applies.I'm not understanding how variable input could have any effect within any kind of reasonably designed code, where processing an empty list would be a bad idea.

2019年08月19日11分27秒

DJK -Nope, I think you’re still missing it.Presumably you want to DO something with a list, if you have one.What would you do differently if it were empty?Return early?What if it isn’t empty? process it?The point is, still, that you probably don’t need to check for an empty list, just iterate over it and do whatever you were going to do with the elements.If there are no elements, you fall through.If there are elements, you process them as you need to.The point is NOT to use the example FOR an empty-check but rather to NOT check at all, just process the list.

2019年08月19日11分27秒

It's pretty rare that you're going to have an exhaustive list of 6 types that you want to accept and not be flexible for any other types. When you need that kind of thing, you probably want an ABC. In this case, it would probably be one of the stdlib ABCs, like collections.abc.Sized or collections.abc.Sequence, but it might be one you write yourself and register(list) on. If you actually do have code where it's important to distinguish empty from other falsey, and also to distinguish lists and tuples from any other sequences, then this is correct—but I don't believe you have such code.

2019年08月19日11分27秒

The reason people don't like this is because it's entirely unnessesary in most cases. Python is a duck-typed language, and this level of defensive coding actively hinders that. The idea behind Python's type system is that things should work as long as the object passed in functions in the way it needs to. By doing explicit type checks you are forcing the caller to use specific types, going against the very grain of the language. While occasionally such things are necessary (excluding strings from being treated as sequences), such cases are rare and almost always best as blacklists.

2019年08月19日11分27秒

If you really want to check that the value is exactly [] and not something falsy of another type, then surely if a == []: is called for, rather than mucking about with isinstance.

2019年08月20日11分27秒

There are some automatic coercions for == though. Off the top of my head, I can't identify any for []. [] == () for instance returns False. But for example frozenset()==set() returns True. So it's worth at least giving some thought to whether some undesired type might be coerced to [] (or vice versa) when doing a == [].

2019年08月19日11分27秒

RemcoGerlich - isinstance() is still preferable as opposed to constructing an empty list to compare against.Also, as another pointed out, the equality operator may invoke implicit conversion of some types, which may be undesirable.There is no reason to ever code "a == []" and that code would definitely be flagged as a defect in any code review I've participated in.Using the appropriate tool as provided by the language should not be considered "mucking about," but rather "good programming technique."

2019年08月19日11分27秒

how do we assert this when using unite testing?

2019年08月19日11分27秒

DJ_Stuffy_K assert what in unit testing, an empty list? Just use assert(not myList). If you also want to assert the object is a list, you can use assertIsInstance().

2019年08月19日11分27秒

This is going to be slower, as you instantiate an extra empty list unnecessarily.

2019年08月19日11分27秒

this is less readable than if not a: and breaks more easily. Please don't do it.

2019年08月19日11分27秒

There is a good point made earlier () == [] is also equal to false. Although I like how this implementation reads the if not a: covers all cases, if you are definitely expecting a list then your example should be sufficient.

2019年08月19日11分27秒

It is possible this throws an exception, if a is not a list and a has no method __len__ implemented. I would recommend: if isinstance(obj, list): if len(obj) == 0:print '...'

2019年08月19日11分27秒

SvenKrüger nope. Operator and is lazy in Python. Nothing after and is going to be executed if condition before and is False.

2019年08月19日11分27秒

This is true in many programming languages, not just Python

2019年08月19日11分27秒

Overbroad; this is just asking whether a list is empty, not whether something is an empty iterable.

2019年08月19日11分27秒

If I wasn't happy with if a:, it would be because I wanted an exception if a wasn't some sort of container.(Being an iterable also allows iterators, which can't usefully be tested for emptiness.)

2019年08月19日11分27秒

please give more explanation about how it is working without writing "if"?

2019年08月19日11分27秒

This is not pythonic nor a complete example.Also, It instantiates an empty list every time it is encountered.Don't do this.

2019年08月19日11分27秒

For those (like me) who didn't know, bool() converts a Python variable into a boolean so you can store the truthiness or falsiness of a value without having to use an if-statement. I think it's less readable than simply using a conditional like the accepted answer, but I'm sure there are other good use cases for it.

2019年08月19日11分27秒

This is usable in an expression and is more terse.

2019年08月19日11分27秒

-1 - To avoid confusion, don't use a reserved words for variable names or you may get surprising behavior next time you try to call, for instance "list()"... something like "TypeError: 'list' object is not callable" or some such.

2019年08月19日11分27秒

The name is_empty suggests that it returns something.But if it did, that something would just be bool(any_structure), which you should use instead (when you need a bool at all).

2019年08月19日11分27秒

Why do we want a variation on bool that (also) prints messages to standard output?

2019年08月19日11分27秒

DavisHerring We alwayshave two choice first is to print using function other is using return bool variable. Choice is yours. I write both so you can choose between them.

2019年08月19日11分27秒

all(bool(x) for x in l) is True for an empty list

2019年08月19日11分27秒

I see that pylint complains about this: >>> timeit.timeit(setup='None', stmt="list=[]; bool(list)", number=10000) 0.0009641999999985273 >>> timeit.timeit(setup='None', stmt="list=[]; bool(len(list))", number=10000) 0.002756199999993214 it is way slower

2019年08月19日11分27秒

Doesn't this destroy the last item in the list?

2019年08月19日11分27秒

ifconfig Yeah it does

2019年08月19日11分27秒

Why is this behavior desireable?

2019年08月19日11分27秒

That is very bad

2019年08月19日11分27秒

Worst, in fact. BTW, what does unofficial approach mean anyway?

2019年08月19日11分27秒

Yes,I was just searching for some vulgar answer.

2019年08月19日11分27秒

This guy (BoRRis) has been posting "wierd"answers all over Stack Overflow now.

2019年08月19日11分27秒