Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

That still looks like something that a novice might trip over when reading this. Just describing what it does is already a bit convoluted: it tests whether any value of a list of booleans, produced by a generator expression by testing membership of a value in some other list, is True.

I would have gone with the following, as it requires less mental unpacking:

  if set(args) & set(["-h", "--help"]):
      display_help()
Also, note that any() works with any iterable, the outer brackets are not needed given the list expression.

  if any(a in ["-h", "--help"] for a in args):
      display_help()


Being extremely pedantic, omitting the outer ()s is legal for a generator comprehension. That is, the following are equivalent:

  foo(x for x in xs)

  foo((x for x in xs))

  gen = (x for x in xs)
  foo(gen)
But these are not the same as:

  foo([x for x in xs]

  lst = [x for x in xs]
  foo(lst)
It doesn't matter in this tiny example, but the difference between generators and lists can be very very important when working on very large amounts of data (e.g. processing a big text corpus), or a potentially-infinite stream of data.


on my phone and a bit discombobulated today, so we’ll see how i go with this

> That still looks like something that a novice might trip over when reading this.

my experience with “juniors” who start with python is that they think in lists and dictionaries. they don’t think in terms of set theory. that’s just the way python is taught.

i would definitely set interview questions where a “decent” solution involves using sets and see who gets it without iterating over lists (ha, setting an interview question on sets… geddit? i’ll see myself out).

> Just describing what it does is already a bit convoluted

yeah, but python only/main “juniors” primarily think in terms of lists, see above.

so, between making sure all juniors can read the code versus doing it succinctly, but juniors all need to learn about sets — practicality wins out quite often.

> I would have gone with the following, as it requires less mental unpacking:

> if set(args) & set(["-h", "--help"]):

> display_help()

if i were reviewing this code i’d ask you to switch it to

    if set(args).intersection(set(["-h", "--help"])):
it is more verbose and more brackets, but it is more explicit and obvious what is happening to some junior who has never dealt with sets before (hmm what’s an intersection? should probably google it)

& is also used for the bitwise AND operator. plus some other stuff in various frameworks like django. so could lead to some confusion.

> Also, note that any() works with any iterable, the outer brackets are not needed given the list expression.

i generally HATE the overuse of generator expressions in python. everyone writes absolutely everything as an inline generator expression, making it hard to test.

but, rant aside, yes, this is probably the one i would pick during a review (likely after a discussion about how using the intersection method makes things less legible and then this gets suggested somewhere).

people don’t realise not every genexp needs to be a list. easy mistake to make with the “everything is a list or a dict” mental model.


".intersection()" takes any iterable, it can be:

    if set(args).intersection(["-h", "--help"]):
Also python has had a special syntax for sets since 2.7 (I think), though I haven't seen it used very often:

    if {"-h", "--help"}.intersection(args):


It makes so much sense to think about this as sets, thanks




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: