相关疑难解决方法(0)

在Python中,如何确定对象是否可迭代?

有方法isiterable吗?到目前为止我找到的唯一解决方案是打电话

hasattr(myObj, '__iter__')
Run Code Online (Sandbox Code Playgroud)

但我不确定这是多么万无一失.

python iterable

994
推荐指数
14
解决办法
41万
查看次数

在python中有一种方法可以在调用之前检查函数是否是"生成器函数"?

可以说我有两个功能:

def foo():
  return 'foo'

def bar():
  yield 'bar'
Run Code Online (Sandbox Code Playgroud)

第一个是正常函数,第二个是生成器函数.现在我想写这样的东西:

def run(func):
  if is_generator_function(func):
     gen = func()
     gen.next()
     #... run the generator ...
  else:
     func()
Run Code Online (Sandbox Code Playgroud)

什么是直截了当的实现is_generator_function()?使用types包我可以测试是否 gen是生成器,但我希望在调用之前这样做func().

现在考虑以下情况:

def goo():
  if False:
     yield
  else:
     return
Run Code Online (Sandbox Code Playgroud)

调用goo()将返回生成器.我假设python解析器知道该goo()函数有一个yield语句,我想知道是否可以轻松获取该信息.

谢谢!

python function generator coroutine

57
推荐指数
3
解决办法
7533
查看次数

enumerate()是否生成生成器对象?

作为一个完整的Python新手,它肯定是这样的.运行以下...

x = enumerate(['fee', 'fie', 'foe'])
x.next()
# Out[1]: (0, 'fee')

list(x)
# Out[2]: [(1, 'fie'), (2, 'foe')]

list(x)
# Out[3]: []
Run Code Online (Sandbox Code Playgroud)

......我注意到:(a)x确实有一个next方法,似乎是生成器所需要的,而(b)x只能迭代一次,这个着名的python标签答案中强调了生成器的一个特征.

在另一方面,这两个最高度upvoted回答这个问题, 如何确定一个对象是否是发电机似乎表明,enumerate()不会返回发电机.

import types
import inspect

x = enumerate(['fee', 'fie', 'foe'])

isinstance(x, types.GeneratorType)
# Out[4]: False

inspect.isgenerator(x)
# Out[5]: False
Run Code Online (Sandbox Code Playgroud)

......虽然对该问题的第三个低调的回答似乎表明实际上enumerate() 确实返回了一个发电机:

def isgenerator(iterable):
    return hasattr(iterable,'__iter__') and not hasattr(iterable,'__len__')

isgenerator(x)
# Out[8]: True
Run Code Online (Sandbox Code Playgroud)

发生什么了?是x发电机还是没有?它在某种意义上是"类似发电机",但不是真正的发电机吗?Python使用duck-typing是否意味着上面最后一个代码块中概述的测试实际上是最好的?

我不会继续写下我头脑中可能存在的可能性,而是将其抛给那些立即知道答案的人.

python

31
推荐指数
2
解决办法
6233
查看次数

确保一个参数可以迭代两次

假设我有以下函数:

def print_twice(x):
    for i in x: print(i)
    for i in x: print(i)
Run Code Online (Sandbox Code Playgroud)

当我跑步时:

print_twice([1,2,3])
Run Code Online (Sandbox Code Playgroud)

或者:

print_twice((1,2,3))
Run Code Online (Sandbox Code Playgroud)

我得到了预期的结果:数字 1,2,3 被打印两次。

但是当我跑步时:

print_twice(zip([1,2,3],[4,5,6]))
Run Code Online (Sandbox Code Playgroud)

(1,4),(2,5),(3,6) 对仅打印一次。可能这是因为zip返回一个在一次传递后终止的生成器。

如何修改该函数print_twice以使其正确处理所有输入?

我可以在函数的开头插入一行:x = list(x)。但如果 x 已经是列表、元组、范围或任何其他可以迭代多次的迭代器,这可能会效率低下。有更有效的解决方案吗?

python

8
推荐指数
2
解决办法
410
查看次数

Python3 中的惰性求值

假设我有一个有副作用的函数(在这个例子中,副作用是打印了一些东西)。是否有任何版本的 any() 或列表可迭代的任何构造在找到 True 结果后不会触发副作用?

例如,假设这个函数:

def a(x):
   print("A function got: " + str(x))
   return x == 2
Run Code Online (Sandbox Code Playgroud)

人们可能希望这个电话能奏效。当然,它不会:

any([
  a(i) for i in range(5)
])
Run Code Online (Sandbox Code Playgroud)

哪个打印:

A function got: 0
A function got: 1
A function got: 2
A function got: 3
A function got: 4
Run Code Online (Sandbox Code Playgroud)

但我希望它打印出来:

A function got: 0
A function got: 1
A function got: 2
Run Code Online (Sandbox Code Playgroud)

为什么?Range 是一个可迭代的,列表推导正在产生一个可迭代的,我有点希望 Python 将它们链接在一起并在 any() 函数停止消耗后立即停止执行整个事情,一旦它达到第一个 True 就应该这样做.

我有什么误解?如果有的话,哪个版本会以这种方式运行?

python lazy-evaluation

5
推荐指数
1
解决办法
379
查看次数

生成器对象上的断言

是否有用于内省生成器对象的技术(例如单元测试中的断言)?

更具体地说,我有一个数据处理管道,由一系列小函数组成,这些函数通常应用于列表理解或生成器表达式内的值,如下所示:

生成一些随机数据:

>>> raw_data = ["${}".format(RND.randint(10, 100)) for c in range(10)]

>>> # a function that does some sort of of transform
>>> fnx = lambda q: float(q.replace('$', ''))

>>> d1 = [fnx(itm) for itm in raw_data]
Run Code Online (Sandbox Code Playgroud)

在下一步中,另一个变换函数将应用于d1的项目,依此类推。

在上面的例子中,例如,关于prices_clean的长度或其值的最小/最大等的断言是我的单元测试套件的核心:

>>> assert len(d1) == 10
Run Code Online (Sandbox Code Playgroud)

鉴于我只是要迭代这些中间结果,我实际上不需要列表,生成器对象就可以了,并且考虑到内存配置文件要低得多,这就是我使用的:

>>> d1 = (fnx(itm) for itm in raw_data)
Run Code Online (Sandbox Code Playgroud)

当然,我在使用列表推导式时所依赖的断言不适用于生成器对象:

>>> d1
  <generator object <genexpr> at 0x106da9230>

>>> assert len(d1) == 10
  Traceback (most recent call last):
  File "<pyshell#33>", line 1, …
Run Code Online (Sandbox Code Playgroud)

python unit-testing generator assertion

3
推荐指数
1
解决办法
7399
查看次数

Psycopg2 cursor.execute返回生成器

假设我只有1GB的内存和1TB的硬盘空间。

这是我的代码,我正在使用postgres数据库。

import psycopg2

try:
   db = psycopg2.connect("database parameters")
   conn = db.cursor()
   conn.execute(query) 

   #At this point, i am running 
   for row in conn:
Run Code Online (Sandbox Code Playgroud)

对于这种情况,我想可以肯定地认为conn是一个生成器,因为我似乎无法在线找到确定的答案,并且由于无法承受系统崩溃而无法在自己的环境中尝试使用。

我期望此查询返回的数据超过100 GB

我正在使用python 2.7和psycopg2库

python database postgresql

3
推荐指数
1
解决办法
1374
查看次数