简体   繁体   中英

Is there a `let` or `as` keyword for Python generators?

I'm coming to Python from Clojure, and was wondering if there is a way to have a "temporary variable" inside a generator.

In Clojure, I can use a let inside a for generator to name an intermediary computation on the item:

(def fnames ["abc1234" "abcdef" "1024"])
(for [fname fnames
      :let [matches (re-matches #"(\w+?)(\d+)" fname)]
      :when matches]
  matches)
;=> (["abc10" "abc" "1234"] ["1024" "1" "024"])

In Python, I need to use a generator twice to filter out the None results:

fnames = ["abc1234", "abcdef", "1024"]
matches = [re.match('(\w+?)(\d+)', fname) for fname in fnames]
matches = [match.groups() for match in matches if match is not None]
# [('abc', '1234'), ('1', '024')]

So, is there a way to do something like the following? If not, what is the most Pythonic way?

matches = [re.match('(\w+?)(\d+)', fname) as match 
   for fname in fnames
   if match is not None]

No, there is no direct equivalent of Clojure's let . The basic structure of Python's list comprehension is:

[name for name in iterable if condition]

where the if condition part is optional. That is all that the grammar provides for.


In your specific case though, you could put a generator expression inside the list comprehension:

matches = [m.groups() for m in (re.match('(\w+?)(\d+)', f) for f in fnames) if m]

Demo:

>>> import re
>>> fnames = ["abc1234", "abcdef", "1024"]
>>> matches = [m.groups() for m in (re.match('(\w+?)(\d+)', f) for f in fnames) if m]
>>> matches
[('abc', '1234'), ('1', '024')]
>>>

Also, you will notice that I removed the is not None part of your condition. While it is generally a good idea to explicitly test for None , it is not needed in this case since re.match always returns either a match object (a truthy value) or None (a falsey value).

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