如何重复一个列表以匹配另一个列表的长度?

huangapple go评论78阅读模式
英文:

How to repeat one list to match the length of another?

问题

我有两个列表:

A = ['a', 'b', 'c', 'd', 'e']
B = ['c', 'a', 't']

如何使B的项目重复以匹配A的长度?

C = ['c', 'a', 't', 'c', 'a']

或者,是否也可能将A和B组合以生成:

C = ['ac', 'ba', 'ct', 'dc', 'ea']
英文:

I have two lists:

A = ['a', 'b', 'c', 'd', 'e']
B = ['c', 'a', 't']

How could I repeat the items of B to match the length of A?

C = ['c', 'a', 't', 'c', 'a']

Alternatively, would it also be possible to combine A and B to yield:

C = ['ac', 'ba', 'ct', 'dc', 'ea']

答案1

得分: 4

以下是翻译好的内容:

"逻辑不清晰,但假设你想要重复 B 的项目,直到与 A 的长度匹配,请使用 itertools.cycleitertools.islice:"

from itertools import cycle, islice

A = ['a', 'b', 'c', 'd', 'e']
B = ['c', 'a', 't']

C = list(islice(cycle(B), len(A)))

输出:['c', 'a', 't', 'c', 'a']

为了好玩,另一种(效率较低)的方法,但没有导入,重复然后切片 A

C = (B*-(-len(A)//len(B)))[:len(A)]

# -(-len(A)//len(B)) 是获取 len(A)/len(B) 的上取整值的技巧
结合 A 和 B
from itertools import cycle

C = [''.join(x) for x in zip(A, cycle(B))]

# 或者
C = [f'{a}{b}' for a, b in zip(A, cycle(B))]

输出:['ac', 'ba', 'ct', 'dc', 'ea']

英文:

The logic is unclear, but assuming that you want to repeat the items of B as many times as needed to match the length of A, use itertools.cycle and itertools.islice:

from itertools import cycle, islice

A = ['a', 'b', 'c', 'd', 'e']
B = ['c', 'a', 't']

C = list(islice(cycle(B), len(A)))

Output: ['c', 'a', 't', 'c', 'a']

For fun, another (less efficient) approach but without imports, repeating, then slicing A:

C = (B*-(-len(A)//len(B)))[:len(A)]

# -(-len(A)//len(B)) is a trick to get the ceiled value of len(A)/len(B)
combining A and B
from itertools import cycle

C = [''.join(x) for x in zip(A, cycle(B))]

# or
C = [f'{a}{b}' for a, b in zip(A, cycle(B))]

Output: ['ac', 'ba', 'ct', 'dc', 'ea']

答案2

得分: 3

重复一个 list n 次,使用 ls * n

示例:

ls = ['d', 'o', 'g']
ls * 3

输出是:

['d', 'o', 'g', 'd', 'o', 'g', 'd', 'o', 'g']

要添加部分重复,使用切片来获取最后一部分重复并添加到完整的重复部分,您可以使用 divmod 来获取所需的完整重复部分和余数:

ls = ['s', 'i', 'n', 'g', 'u', 'l', 'a', 'r', 'i', 't', 'y']
n = 24
f, r = divmod(n, len(ls))
ls * f + ls[:r]

输出:

['s', 'i', 'n', 'g', 'u', 'l', 'a', 'r', 'i', 't', 'y', 's', 'i', 'n', 'g', 'u', 'l', 'a', 'r', 'i', 't', 'y', 's', 'i']

您可以将其包装在一个函数中,以便轻松重复使用:

def repeat(ls, n):
    f, r = divmod(n, len(ls))
    return ls * f + ls[:r]

示例用法:

repeat('Python', 16)

您还可以使用列表推导来做到这一点,只需使用模运算来在索引大于或等于列表长度时缩小索引:

def repeat_listcomp(ls, n):
    l = len(ls)
    return [ls[i % l] for i in range(n)]

第一个保留了参数的数据类型,第二个没有。

需要注意的是,接受的答案比我的列表推导解决方案更高效,但比我的原始解决方案慢得多(我误将 ns 写成了 µs),我的代码帮助您更好地理解它:

%timeit repeat_listcomp('abcdefghijklmnopqrstuvwxyz', 2048)
%timeit repeat('abcdefghijklmnopqrstuvwxyz', 2048)

还有一种使用 itertools 的方法:

from itertools import cycle, islice
list(islice(cycle('abcdefghijklmnopqrstuvwxyz'), 2048))

这些都是不同方法来重复一个列表。

英文:

To repeat a list n times, use ls * n.

Example:

ls = ['d', 'o', 'g']
ls * 3

Output is:

['d', 'o', 'g', 'd', 'o', 'g', 'd', 'o', 'g']

To add partial repetitions, use slicing to get the last partial repetition and add to full repetitions, you can get the required full repetitions and remainder by using divmod:

ls = ['s', 'i', 'n', 'g', 'u', 'l', 'a', 'r', 'i', 't', 'y']
n = 24
f, r = divmod(n, len(ls))
ls * f + ls[:r]

Output:

['s', 'i', 'n', 'g', 'u', 'l', 'a', 'r', 'i', 't', 'y', 's', 'i', 'n', 'g', 'u', 'l', 'a', 'r', 'i', 't', 'y', 's', 'i']

You can wrap it in a function so that you can easily reuse it:

def repeat(ls, n):
    f, r = divmod(n, len(ls))
    return ls * f + ls[:r]

Example usage:

In [595]: repeat('Python', 16)
Out[595]: 'PythonPythonPyth'

You can also use a list comprehension to do that, just use modular arithmetic to scale down the index when it is greater than or equal to the length of the list:

def repeat_listcomp(ls, n):
    l = len(ls)
    return [ls[i%l] for i in range(n)]

The first preserves the data type of the argument, the second doesn't.


I should add the accepted answer is much more efficient than my list comprehension solution but much slower than my original solution (I mistook the ns to µs), and my code helps you understand it better:

In [598]: %timeit repeat_listcomp('abcdefghijklmnopqrstuvwxyz', 2048)
150 µs ± 1.85 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

In [599]: %timeit repeat('abcdefghijklmnopqrstuvwxyz', 2048)
754 ns ± 21.1 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

In [600]: from itertools import cycle, islice

In [601]: %timeit list(islice(cycle('abcdefghijklmnopqrstuvwxyz'), 2048))
32.9 µs ± 821 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

答案3

得分: 1

我明白你想要一个将"cat"单词放入A列表的长度的脚本:

这是用Python编写的。

A = ['a', 'b', 'c', 'd', 'e']

B = ['c', 'a', 't']

C = []
C_combine_A_B = []

b_len = len(B)
a_len = len(A)

i = 0
while i < a_len:
    C.append(B[i % b_len])
    C_combine_A_B.append(A[i] + B[i % b_len])
    i += 1

print(C)
print(C_combine_A_B)

如果你有不理解的地方,请告诉我,我会解释给你听。

编辑:添加了组合列表的实现。

英文:

I have understand that you want a script which put cat word the len of A list:

It is written in Python.

A = [&#39;a&#39; , &#39;b&#39; , &#39;c&#39; , &#39;d&#39; , &#39;e&#39;]

B = [&#39;c&#39; , &#39;a&#39; , &#39;t&#39;]

C = []
C_combine_A_B = []

b_len = len(B)
a_len = len(A)

i = 0
while i &lt; a_len:
    C.append(B[i%b_len])
    C_combine_A_B.append(A[i]+B[i%b_len])
    i+=1

print(C)
print(C_combine_A_B)

If you do not understand something tell me and I will explain you.

EDIT: combined list impl added

答案4

得分: 0

C = B + [x for x in B if x in A]
由于没有明确的逻辑解释,获得所需的C列表的最直接方法是将B列表与包含在B列表中的A列表的元素连接起来。

英文:
C = B + [x for x in B if x in A]

As there's no clear explanation of logic, the most straightforward approach to get desired C list is to concatenate B list with elements of A list that B list contains.

答案5

得分: 0

你可以使用divmod来计算重复B多少次以及在末尾添加什么额外范围:

A = ['a', 'b', 'c', 'd', 'e']
B = ['c', 'a', 't']

r, x = divmod(len(A), len(B))  # 重复次数,额外部分
C = B * r + B[:x]

print(C)
['c', 'a', 't', 'c', 'a']

另一种方法是使用extend:

C = B[:len(A)]
C.extend(C[i] for i in range(len(A) - len(B)))

print(C)
['c', 'a', 't', 'c', 'a']

对于你的替代方法,可以使用带有模数索引的列表推导式:

C = [a + B[i % len(B)] for i, a in enumerate(A)]

print(C)
['ac', 'ba', 'ct', 'dc', 'ea']

或者使用复杂的map/zip:

*C, = map("".join, zip(A, B * (1 + len(A) // len(B))))

print(C)
['ac', 'ba', 'ct', 'dc', 'ea']

# 或者使用itertools:

from itertools import cycle
*C, = map("".join, zip(A, cycle(B)))
英文:

You could use divmod to compute how many times to repeat B and what extra range to add at the end:

A = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;]
B = [&#39;c&#39;, &#39;a&#39;, &#39;t&#39;]

r,x = divmod(len(A),len(B))  # repeats, extra
C   = B*r + B[:x]

print(C)
[&#39;c&#39;, &#39;a&#39;, &#39;t&#39;, &#39;c&#39;, &#39;a&#39;]

Another approach could be to use extend:

C = B[:len(A)]
C.extend( C[i] for i in range(len(A)-len(B)) )

print(C)
[&#39;c&#39;, &#39;a&#39;, &#39;t&#39;, &#39;c&#39;, &#39;a&#39;]

For your alternate approach, a list comprehension with modulo indexing could do it:

C = [a+B[i%len(B)] for i,a in enumerate(A)]

print(C)
[&#39;ac&#39;, &#39;ba&#39;, &#39;ct&#39;, &#39;dc&#39;, &#39;ea&#39;]

or a gnarly map/zip:

*C, = map(&quot;&quot;.join,zip(A,B*(1+len(A)//len(B))))

print(C)
[&#39;ac&#39;, &#39;ba&#39;, &#39;ct&#39;, &#39;dc&#39;, &#39;ea&#39;]

# or using itertools:

from itertools import cycle
*C, = map(&quot;&quot;.join,zip(A,cycle(B)))

huangapple
  • 本文由 发表于 2023年7月20日 16:03:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76727816.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定