【问题标题】:Python generator objects and .joinPython 生成器对象和 .join
【发布时间】:2013-01-05 00:08:41
【问题描述】:

关于 python 和 .join() 方法的一个基本问题:

file1 = open(f1,"r")
file2 = open(f2,"r")
file3 = open("results","w")

diff = difflib.Differ()
result = diff.compare(file1.read(),file2.read())
file3.write("".join(result)),

上面的 sn-p 代码产生了一个很好的输出,以字符串格式存储在一个名为“results”的文件中,逐行显示两个文件之间的差异。但是我注意到,如果我只使用 .join() 打印“结果”,编译器会返回一条包含内存地址的消息。在尝试使用 .join() 将结果写入文件 without 后,编译器通知我在 .join() 中只能使用字符串和字符缓冲区) 方法,而不是生成器对象。因此,根据我引用的所有证据,如果我错了,请纠正我:

  1. result = diff.compare(file1.read(),file2.read())

  2. result 是一个字符串列表,result 本身就是对第一个字符串的引用?

  3. .join() 获取内存地址并指向第一个,然后遍历该结构中字符串的其余地址?

  4. 生成器对象是返回指针的对象吗?

如果我的问题不清楚,我很抱歉,但我主要是想问问蟒蛇老兵我的推论是否正确。我的问题不是关于可观察的结果,而是关于 python 的内部工作原理。感谢您的所有帮助。

【问题讨论】:

  • 你没有内存地址; python给你一个对象的表示,自定义对象的默认是显示对象的类型和内存地址。那里还有一个物体。

标签: python string list pointers generator


【解决方案1】:

join 是一种字符串方法。该方法采用任何可迭代对象并对其进行迭代并将内容连接在一起。 (内容必须是字符串,否则会引发异常。)

如果您尝试将生成器对象直接写入文件,您将只获取生成器对象本身,而不是其内容。 join“展开”生成器的内容。

您可以看到一个简单、显式的生成器发生了什么:

def gen():
    yield 'A'
    yield 'B'
    yield 'C'

>>> g = gen()
>>> print g
<generator object gen at 0x0000000004BB9090>
>>> print ''.join(g)
ABC

生成器一次分发一个内容。如果您尝试查看生成器本身,它不会释放任何东西,您只会将其视为“生成器对象”。要获取其内容,您需要遍历它们。您可以使用for 循环、next 函数或任何其他迭代事物的各种其他函数/方法(其中包括str.join)来执行此操作。

当您说结果“是字符串列表”时,您就接近了这个想法。生成器(或可迭代的)有点像“潜在列表”。它实际上不是成为所有内容的列表,而是让您一次剥离每个项目。

没有一个对象是“内存地址”。生成器对象的字符串表示形式(与许多其他对象一样)包括一个内存地址,因此如果您将其打印(如上)或将其写入文件,您将看到该地址。但这并不意味着对象“是”那个内存地址,并且地址本身并不是真正可用的。它只是一个方便的识别标签,因此如果您有多个对象,您可以将它们区分开来。

【讨论】:

  • 请注意,join 假定可迭代对象仅包含/产生字符串。如果不是这样,它会抱怨......
  • 有趣的事实:给''.join() 一个生成器比给''.join() 在一个生成器上调用list() 的结果''.join(list(result))''.join(result) 快。
  • @Marcin:消息是:
  • @BrenBarn,太好了,所以 .join() 基本上是在设置一个指针,该指针在生成器上进行迭代,并访问内容并与它们相邻。这让我想起了在 C 中访问字符数组的一种更简单的形式。再次感谢!
  • @Phob 请参阅stackoverflow.com/a/9061024/100297。检查你的基准,你可能在第一次运行时耗尽了你的发电机。
猜你喜欢
  • 2012-09-10
  • 2010-10-31
  • 2018-12-05
  • 2019-10-18
  • 2020-03-09
  • 2017-07-24
  • 2015-03-03
  • 2022-01-15
  • 2010-11-19
相关资源
最近更新 更多