[英]Python List comprehension - returned tuples seem to change when they are iterated and printed
下面的代码在一个类中使用,每个变量的示例如下。 该代码的预期功能是将self.users中的用户列表分成(尽可能接近)相等的块,并返回self.text_list中的对象的元组和一组用户,块由self.text_list中的文本数确定。
注意-python版本是3.6
我在底部重写了列表理解,因此您可以在控制台中运行以查看预期的输出。
def split_by_text_no(self):
user_c = self.users.count()
print('user_c', user_c)
text_c = len(self.text_list)
print('text_c', text_c)
if text_c > 1:
divided = int(ceil(user_c/text_c))
print('divided', divided)
chunks = [(self.text_list[x], self.users[y:y + divided]) for x, y in enumerate(range(0, user_c, divided), 0)]
print('multiple chunks', chunks)
# if this is removed the users assigned in the tuple changes
for chunk in chunks:
print('chunk:',chunk)
for user in chunk[1]:
print(user.phone_number)
# up to here
else:
chunks = [(self.text_list[0], self.users)]
return chunks
最初,注释中的代码不在函数中,并且该函数未按预期执行。 如果:
self.users = [1, 2, 3]
text_c = 2
块列表理解的预期结果将是:
[(self.text_list[0], [1, 2]), (self.text_list[1], [3])]
实际结果是(请注意,列表未拆分,两次显示了用户2):
[(self.text_list[0], [1, 2]), (self.text_list[1], [2])]
这是通过另一个函数中的print语句显示的,该语句非常简单地遍历该函数生成的块。
为了调试它,我在注释中添加了代码:
for chunk in chunks:
print('chunk:',chunk)
for user in chunk[1]:
print(user.phone_number)
令人惊讶的是,这表明每个块中的用户已正确地进行了块化。 现在,遍历这些块并打印每个块中的用户的函数现在还表明用户已正确地进行了块化。
谁能阐明为什么用户未按预期进行拆分,以及为什么打印语句可能会对列表理解产生什么产生影响?
要测试列表理解的预期输出,请参见以下内容:
from math import ceil
users = [1, 2, 3]
user_c = len(users)
text_c = 2
divided = int(ceil(user_c/text_c))
chunks = [(print(x), users[y:y + divided]) for x, y in enumerate(range(0, user_c, divided), 0)]
这将产生:
[(None, [1, 2]), (None, [3])]
但是,如上所述,这不是我的函数产生的。
我知道这是一个很大的问题,如果需要澄清,请在评论中提出,我会进行调整。
在我的情况下,该控制台从函数输出而没有注释中的代码
user_c 3
text_c 2
divided 2
multiple chunks [((UUID('c02d749b-c27f-4565-a1d2-f5c61fb46664'), 'test %FIRSTNAME%'), <QuerySet [<User: User object>, <User: User object>]>), ((UUID('2c223554-cf31-437d-84e1-d156f0d4721b'), 'test1%FIRSTNAME%'), <QuerySet [<User: User object>]>)]
chunk 0
user is 12fbc56c-93e3-49dd-8366-5e24fc4e40a0
user is fffbc56c-93e3-49dd-8366-5e24fc4e40a0
chunk 1
user is fffbc56c-93e3-49dd-8366-5e24fc4e40a0
如您所见,用户的uuid在块0和块1中相同
这是注释中的代码
user_c 3
text_c 2
divided 2
multiple chunks [((UUID('c02d749b-c27f-4565-a1d2-f5c61fb46664'), 'test %FIRSTNAME%'), <QuerySet [<User: User object>, <User: User object>]>), ((UUID('2c223554-cf31-437d-84e1-d156f0d4721b'), 'test1%FIRSTNAME%'), <QuerySet [<User: User object>]>)]
((UUID('c02d749b-c27f-4565-a1d2-f5c61fb46664'), 'test %FIRSTNAME%'), <QuerySet [<User: User object>, <User: User object>]>)
12fbc56c-93e3-49dd-8366-5e24fc4e40a0
abcbc56c-93e3-49dd-8366-5e24fc4e40a0
((UUID('2c223554-cf31-437d-84e1-d156f0d4721b'), 'test1%FIRSTNAME%'), <QuerySet [<User: User object>]>)
fffbc56c-93e3-49dd-8366-5e24fc4e40a0
chunk 0
user is 12fbc56c-93e3-49dd-8366-5e24fc4e40a0
user is abcbc56c-93e3-49dd-8366-5e24fc4e40a0
chunk 1
user is fffbc56c-93e3-49dd-8366-5e24fc4e40a0
在这种情况下,uuid都不同
如果我运行您的代码(我正在使用python 2.7)
from __future__ import print_function
from math import ceil
users = [1, 2, 3]
user_c = len(users)
text_c = 2
divided = int(ceil(user_c/text_c))
chunks = [(print(x), users[y:y + divided]) for x, y in enumerate(range(0, user_c, divided), 0)]
print(chunks)
我有
1
2
3
[(None, [1]), (None, [2]), (None, [3])]
如果我更改了text_c = 2.0
我有
0
1
[(None, [1, 2]), (None, [3])]
那是你要的吗? 如果是这样,也许检查代码中的除数值
为了调用和测试您的原始功能,我对其做了一些修改
text_list = ['text_1', 'text_2']
users = [1, 2, 3]
def split_by_text_no():
user_c = 3
print('user_c', user_c)
text_c = len(text_list)
print('text_c', text_c)
if text_c > 1:
divided = int(ceil(user_c/text_c))
print('divided', divided)
chunks = [(text_list[x], users[y:y + divided]) for x, y in enumerate(range(0, user_c, divided), 0)]
else:
chunks = [(text_list[0], users)]
return chunks
print(split_by_text_no())
一样吗 我静止不动
user_c 3
text_c 2
divided 2
[('text_1', [1, 2]), ('text_2', [3])]
这样对吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.