Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我们如何在python中对列表的元素进行riffle洗牌?_Python - Fatal编程技术网

我们如何在python中对列表的元素进行riffle洗牌?

我们如何在python中对列表的元素进行riffle洗牌?,python,Python,我想在不导入任何模块的情况下对列表中的元素进行洗牌。 洗牌的类型是即兴洗牌。将列表中的元素数分成两部分,然后交错 如果有奇数个元素,那么后半部分应该包含额外的元素 例如:列表=[1,2,3,4,5,6,7] then the final list should look like [1,4,2,5,3,6,7] 通过利用Python中迭代器的next特性,您可以相当轻松地完成这项工作 您要做的第一件事是将元素分成两部分 接下来,使用Python的iter函数将这两部分转换为迭代器。您可以跳过这

我想在不导入任何模块的情况下对列表中的元素进行洗牌。 洗牌的类型是即兴洗牌。将列表中的元素数分成两部分,然后交错

如果有奇数个元素,那么后半部分应该包含额外的元素

例如:列表=[1,2,3,4,5,6,7]

then the final list should look like [1,4,2,5,3,6,7]

通过利用Python中迭代器的
next
特性,您可以相当轻松地完成这项工作

您要做的第一件事是将元素分成两部分

接下来,使用Python的
iter
函数将这两部分转换为迭代器。您可以跳过这一步,但我发现调用
next(iterable)
比手动索引列表要干净得多

最后,您将循环浏览列表的前半部分,对于添加的每一个元素,添加后半部分的对应元素(调用
next
将给出序列中的下一项)

例如:

elements = [1,2,3,4,5,6,7]

half_point = len(elements)/2

a = iter(elements[0:half_point])
b = iter(elements[half_point: ])

result = []
for i in range(half_point):
    result.append(next(a))
    result.append(next(b))

if len(elements) % 2 != 0:
    result.append(next(b))

print result

>>> [1, 4, 2, 5, 3, 6, 7]
底部的最后一位检查列表是否为奇数。如果是,则将最后一个元素附加到列表的末尾


如果你有创意的话,你可以先压缩再解包,把它压缩一点,但我会在你探索
itertools
;)的时候再讨论

您可以将输入列表分为两部分,然后使用zip和一些列表操作来交错项目

n = 9
l = range(1,n+1)
a = l[:n/2]
b = l[n/2:]
c = zip(a,b)
d = list()
for p in c :
    d.extend(list(p))
if n%2==1:
    d.append(b[n/2])
print(d)

当你去调用它时,你可以说交错(列表)

只是为了好玩,一个递归的解决方案:

def interleave(lst1, lst2):
    if not lst1:
        return lst2
    elif not lst2:
        return lst1
    return lst1[0:1] + interleave(lst2, lst1[1:])
在Python2.x中按如下方式使用它(在Python3.x中,使用
/
而不是
/
):

上述方法适用于任意长度的列表,长度是偶数还是奇数都无所谓

>>> ll = list(range(1,8))
>>> mid = len(ll)/2   # for Python3, use '//' operator
>>> it1 = iter(ll[:mid])
>>> it2 = iter(ll[mid:])
>>> riff = sum(zip(it1,it2), ()) + tuple(it2)
>>> riff
(1, 4, 2, 5, 3, 6, 7)
如果这是家庭作业,请准备好解释
sum
zip
如何在这里工作,
sum
的第二个参数是什么,为什么要将
tuple(it2)
添加到末尾,以及此解决方案如何具有内在的低效性

例如:列表=[1,2,3,4,5,6,7] 最后的列表应该是[1,4,2,5,3,6,7]

这里有一个函数可以可靠地执行此操作:

def riffle(deck):
    '''
    Shuffle a list like a deck of cards.
    i.e. given a list, split with second set have the extra if len is odd
    and then interleave, second deck's first item after first deck's first item
    and so on. Thus:
    riffle([1,2,3,4,5,6,7])
    returns [1, 4, 2, 5, 3, 6, 7]
    '''
    cut = len(deck) // 2                        # floor division
    deck, second_deck = deck[:cut], deck[cut:]
    for index, item in enumerate(second_deck):
        insert_index = index*2 + 1
        deck.insert(insert_index, item)
    return deck
并对其进行单元测试

import unittest
class RiffleTestCase(unittest.TestCase):
    def test_riffle(self):
        self.assertEqual(riffle(['a','b','c','d','e']), ['a','c','b','d','e'])
        self.assertEqual(riffle([1,2,3,4,5,6,7]), [1,4,2,5,3,6,7])

unittest.main()
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

不要测试元素的len是偶数还是奇数,只需执行
result+=list(b)
。如果列表长度为偶数,则
list(b)
将只是一个空列表,否则它将是一个单长度列表,包含原始列表的最后一个元素。@PaulMcGuire+1真聪明!
>>> ll = list(range(1,8))
>>> mid = len(ll)/2   # for Python3, use '//' operator
>>> it1 = iter(ll[:mid])
>>> it2 = iter(ll[mid:])
>>> riff = sum(zip(it1,it2), ()) + tuple(it2)
>>> riff
(1, 4, 2, 5, 3, 6, 7)
def riffle(deck):
    '''
    Shuffle a list like a deck of cards.
    i.e. given a list, split with second set have the extra if len is odd
    and then interleave, second deck's first item after first deck's first item
    and so on. Thus:
    riffle([1,2,3,4,5,6,7])
    returns [1, 4, 2, 5, 3, 6, 7]
    '''
    cut = len(deck) // 2                        # floor division
    deck, second_deck = deck[:cut], deck[cut:]
    for index, item in enumerate(second_deck):
        insert_index = index*2 + 1
        deck.insert(insert_index, item)
    return deck
import unittest
class RiffleTestCase(unittest.TestCase):
    def test_riffle(self):
        self.assertEqual(riffle(['a','b','c','d','e']), ['a','c','b','d','e'])
        self.assertEqual(riffle([1,2,3,4,5,6,7]), [1,4,2,5,3,6,7])

unittest.main()
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK