Python列表理解 - 返回的元组在迭代和打印时似乎会发生变化

时间:2017-06-13 11:53:45

标签: python list-comprehension

下面的代码在一个类中使用,下面是每个变量的外观示例。代码的预期功能是将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在chunk 0和chunk 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

在这种情况下,uuids都是不同的

1 个答案:

答案 0 :(得分:0)

如果我运行你的代码(我正在使用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])]

是不是?