加入两个偏移列表("offset zip"?)
Join two offset lists ("offset zip"?)
考虑两个列表,例如:
L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
M = [1, 2, 3, 4, 5, 6, 7, 8]
假设我们有一对必须匹配的元素 - 例如,(d, 6)
。是否可以 "align" 这些元素的列表,然后加入两个列表中仍有元素的列表 - 有点像 zip 和内部连接之间的交叉?
这可能最好用例子来说明。如上所述使用 L
和 M
:
(d, 6)
会导致 [(a, 3), (b, 4), (c, 5), (d, 6), (e, 7), (f, 8)]
(h, 2)
会导致 [(g, 1), (h, 2)]
(a, 8)
会导致 [(a, 8)]
我的背景:我目前正在尝试构建一个能够通过阅读国际象棋符号来学习下国际象棋的神经网络。这个问题与检查棋盘上的对角线以更新棋子位置有关。例如,如果一个白象刚刚移动到 b7(棋盘右下角的一个方格),那么它一定来自 h1-a8 长对角线上的一个方格或 a6-c8 上的一个方格短对角线。
所以在我的例子中,L
和 M
的长度相同,因为它们对应于 8×8 棋盘上的行列。但总的来说,我认为列表的长度可能不同。
这是一种方法,首先在两个列表中使用 itertools.dropwhile
正向顺序,然后从两个列表中反向获取连接项目之前和之后的项目。
两个生成的可迭代对象然后被链接,但不是在使用itertools.islice
:
从其中一个可迭代对象中删除连接点之后
from itertools import dropwhile, islice, chain
def func(x, y, lst1, lst2):
f1 = lambda i: i!=x
f2 = lambda i: i!=y
r = zip(dropwhile(f1, lst1), dropwhile(f2, lst2))
q = reversed(zip(dropwhile(f1, reversed(lst1)), dropwhile(f2, reversed(lst2))))
return list(chain(q, islice(r, 1, None)))
L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
M = [1, 2, 3, 4, 5, 6, 7, 8]
print(func('d', 6, L, M))
# [('a', 3), ('b', 4), ('c', 5), ('d', 6), ('e', 7), ('f', 8)]
print(func('h', 2, L, M))
# [('g', 1), ('h', 2)]
print(func('a', 8, L, M))
# [('a', 8)]
对两个列表进行两次传递可能效率不高,但惰性求值可以处理大型列表。
你可以按照
的方式做一些事情
L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
M = [1, 2, 3, 4, 5, 6, 7, 8]
m = L.index('h')
n = M.index(2)
if m > n:
m, n = (m - n), 0
else:
m, n = 0, (n - m)
print(list(zip(L[m:], M[n:])))
PS 你可以让 m, n 索引生成更紧凑,但更清楚这个结构应该发生什么。
考虑两个列表,例如:
L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
M = [1, 2, 3, 4, 5, 6, 7, 8]
假设我们有一对必须匹配的元素 - 例如,(d, 6)
。是否可以 "align" 这些元素的列表,然后加入两个列表中仍有元素的列表 - 有点像 zip 和内部连接之间的交叉?
这可能最好用例子来说明。如上所述使用 L
和 M
:
(d, 6)
会导致[(a, 3), (b, 4), (c, 5), (d, 6), (e, 7), (f, 8)]
(h, 2)
会导致[(g, 1), (h, 2)]
(a, 8)
会导致[(a, 8)]
我的背景:我目前正在尝试构建一个能够通过阅读国际象棋符号来学习下国际象棋的神经网络。这个问题与检查棋盘上的对角线以更新棋子位置有关。例如,如果一个白象刚刚移动到 b7(棋盘右下角的一个方格),那么它一定来自 h1-a8 长对角线上的一个方格或 a6-c8 上的一个方格短对角线。
所以在我的例子中,L
和 M
的长度相同,因为它们对应于 8×8 棋盘上的行列。但总的来说,我认为列表的长度可能不同。
这是一种方法,首先在两个列表中使用 itertools.dropwhile
正向顺序,然后从两个列表中反向获取连接项目之前和之后的项目。
两个生成的可迭代对象然后被链接,但不是在使用itertools.islice
:
from itertools import dropwhile, islice, chain
def func(x, y, lst1, lst2):
f1 = lambda i: i!=x
f2 = lambda i: i!=y
r = zip(dropwhile(f1, lst1), dropwhile(f2, lst2))
q = reversed(zip(dropwhile(f1, reversed(lst1)), dropwhile(f2, reversed(lst2))))
return list(chain(q, islice(r, 1, None)))
L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
M = [1, 2, 3, 4, 5, 6, 7, 8]
print(func('d', 6, L, M))
# [('a', 3), ('b', 4), ('c', 5), ('d', 6), ('e', 7), ('f', 8)]
print(func('h', 2, L, M))
# [('g', 1), ('h', 2)]
print(func('a', 8, L, M))
# [('a', 8)]
对两个列表进行两次传递可能效率不高,但惰性求值可以处理大型列表。
你可以按照
的方式做一些事情L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
M = [1, 2, 3, 4, 5, 6, 7, 8]
m = L.index('h')
n = M.index(2)
if m > n:
m, n = (m - n), 0
else:
m, n = 0, (n - m)
print(list(zip(L[m:], M[n:])))
PS 你可以让 m, n 索引生成更紧凑,但更清楚这个结构应该发生什么。