- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想以最同质的方式在 python 中混合两个不同长度的列表。
a = [1,2,3]
b = ['a', 'b', 'c', 'd', 'e', 'f']
a 和 b 的合并列表应该产生
c = ['a', 'b', 1, 'c', 'd', 2, 'e', 'f', 3]
有没有一种Python式的方法来合并这两个列表,如果len(b)/len(a)不是整数也可以工作?
最佳答案
这是解释同质混合的一种方法:假设两个列表的长度分别为 m 和 n。将第一个列表的元素放置在实线的子区间 [0, 1) 上,均匀间隔开,每个元素之间的间隙为 1/m。因此,我们可以将这些元素放置在位置 0/m、1/m、2/m、... (m-1)/m。但还有一些回旋余地:对于 [0, 1) 范围内的任何 x,我们也可以将元素放置在位置 x/m、(x+1)/m、(x+2)/m...。对第二个列表的元素执行相同的操作,将它们放置在彼此距离 1/n 的位置,以便所有元素再次包含在 [0, 1) 中。现在,为了获得两个列表的均匀混合,请按照它们沿实线出现的顺序准确地读取所有元素(从两个列表中)。如果放置位置使得第一个和第二个列表中的元素在一个或多个点上完全重合,则每次发生这种情况时都会优先考虑第一个列表(例如)。
您可以相对轻松地编写这个想法,经过一些简化后,您将得到相当简短而优雅的内容。这是一个生成器函数,它生成混合列表的连续元素:
def mix_lists(l1, l2):
""" Mix two lists evenly, generating the elements of the mixed list. """
m, n = len(l1), len(l2)
for i in range(m + n):
q, r = divmod(i * n, m + n)
yield l1[i - q] if r < m else l2[q]
这对应于我们将第一个列表的元素放置在 [0, 1) 内尽可能靠左的位置,即 0/m, 1/m, ...,以及第二个列表接近最右边的可能位置(因此第一个元素接近 1/n,第二个元素接近 2/n,等等)因此,在我们拥有的自由范围内,第一个列表的元素往往会早于那些元素出现第二个。
这是一个在一个列表的长度是另一个列表的倍数的情况下运行的示例:
>>> list(mix_lists('abcdef', [1, 2, 3]))
['a', 'b', 1, 'c', 'd', 2, 'e', 'f', 3]
还有一些事实并非如此的例子:
>>> list(mix_lists('abcdefgh', range(12)))
['a', 0, 'b', 1, 2, 'c', 3, 'd', 4, 5, 'e', 6, 'f', 7, 8, 'g', 9, 'h', 10, 11]
>>> list(mix_lists('abcdefg', [1, 2, 3, 4]))
['a', 'b', 1, 'c', 'd', 2, 'e', 'f', 3, 'g', 4]
现在,为了进行一些变化,您可以在 divmod
中添加偏移量调用:该偏移量应严格在 0 <= offset < m + n
范围内。调整偏移量相当于移动一个或另一个列表的元素(但移动受到限制,以便所有元素仍然位于区间 [0, 1) 内)。通过改变偏移量,我们得到所有可能的“均匀混合”模式。
def mix_lists(l1, l2, offset=0):
""" Mix two lists evenly, generating the elements of the mixed list. """
m, n = len(l1), len(l2)
for i in range(m + n):
q, r = divmod(i * n + offset, m + n)
yield l1[i - q] if r < m else l2[q]
以下是随着偏移量变化而产生的混合差异的一些示例。
>>> list(mix_lists('abcdefg', [1, 2, 3, 4], offset=0))
['a', 'b', 1, 'c', 'd', 2, 'e', 'f', 3, 'g', 4]
>>> list(mix_lists('abcdefg', [1, 2, 3, 4], offset=2))
['a', 'b', 1, 'c', 2, 'd', 'e', 3, 'f', 'g', 4]
>>> list(mix_lists('abcdefg', [1, 2, 3, 4], offset=5))
['a', 1, 'b', 'c', 2, 'd', 3, 'e', 'f', 4, 'g']
>>> list(mix_lists('abcdefg', [1, 2, 3, 4], offset=9))
[1, 'a', 'b', 2, 'c', 3, 'd', 'e', 4, 'f', 'g']
>>> mix_lists('abcdefg', [1, 2, 3, 4], offset=10)
[1, 'a', 2, 'b', 'c', 3, 'd', 'e', 4, 'f', 'g']
选择 m + n - 1 的最大偏移量会导致第二个列表优于第一个列表,而选择 (m + n)/2 左右的偏移量意味着我们从较长列表中的元素开始,这在一个列表恰好有一个元素比另一个列表长的情况下效果特别好:
>>> list(mix_lists('abcd', [1, 2, 3]))
['a', 'b', 1, 'c', 2, 'd', 3]
>>> list(mix_lists('abcd', [1, 2, 3], offset=3))
['a', 1, 'b', 2, 'c', 3, 'd']
>>> list(mix_lists('abcd', [1, 2, 3], offset=6))
[1, 'a', 2, 'b', 3, 'c', 'd']
关于python - 两个列表的同质混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32338206/
我是一名优秀的程序员,十分优秀!