使用生成器理解与列表理解从文件中读取行

Reading lines from a file using a generator comprehension vs a list comprehension

以下代码来自 Jake VanderPlas 撰写的 Python 数据科学手册第 3 章。文件中的每一行都是有效的 JSON。虽然我认为文件的细节对于回答这个问题并不重要,但文件的 url 是 https://github.com/fictivekin/openrecipes.

# read the entire file into a Python array        
with open('recipeitems-latest.json', 'r') as f:            
    # Extract each line            
    data = (line.strip() for line in f)            
    # Reformat so each line is the element of a list            
    data_json = "[{0}]".format(','.join(data))        
# read the result as a JSON        
recipes = pd.read_json(data_json)

两个问题:

  1. 为什么在代码的第二行中使用生成器理解而不是列表理解?由于所需的最终数据结构是一个列表,我想知道为什么不只使用列表而不是先使用生成器然后再使用列表?
  2. 是否可以改用列表理解?

你有两个问题:

  1. 为什么要生成补偿?因为你事先不知道 JSON 的大小。所以最好注意安全,不要将整个文件加载到内存中。
  2. 是的,可以使用列表理解。只需将括号替换为方括号即可。
>>> f = open('things_which_i_should_know')
>>> data = (line.strip() for line in f)
>>> type(data)
<class 'generator'>
>>> data = [line.strip() for line in f]
>>> type(data)
<class 'list'>
>>> 

请参阅 official documentation 了解更多信息。

With a list comprehension, you get back a Python list; stripped_list is a list containing the resulting lines, not an iterator. Generator expressions return an iterator that computes the values as necessary, not needing to materialize all the values at once. This means that list comprehensions aren’t useful if you’re working with iterators that return an infinite stream or a very large amount of data. Generator expressions are preferable in these situations.