给出一个1和0的序列(列表或numpy数组),如何找到值的相邻子序列数?我想返回类似JSON的字典。
[0, 0, 1, 1, 0, 1, 1, 1, 0, 0]
将返回
{
0: {
1: 1,
2: 2
},
1: {
2: 1,
3: 1
}
}
这是我到目前为止拥有的功能
def foo(arr):
prev = arr[0]
count = 1
lengths = dict.fromkeys(arr, {})
for i in arr[1:]:
if i == prev:
count += 1
else:
if count in lengths[prev].keys():
lengths[prev][count] += 1
else:
lengths[prev][count] = 1
prev = i
count = 1
return lengths
即使列表中出现的字典不同,它也会为0和1输出相同的字典。而且此函数未获取最后一个值。我该如何改善和修复它?另外,如果我的数据位于numpy数组中,numpy是否提供任何更快的方法来解决我的问题? (也许使用np.where(...)
)
答案 0 :(得分:2)
您遇到了Ye Olde复制错误。让我们通过函数来显示问题,添加一行以检查列表中每个字典的对象ID:
lengths = dict.fromkeys(arr, {})
print(id(lengths[0]), id(lengths[1]))
输出:
140130522360928 140130522360928
{0: {2: 2, 1: 1, 3: 1}, 1: {2: 2, 1: 1, 3: 1}}
问题是您将相同字典作为每个键的初始值。当您更新其中任何一个时,都在更改它们都引用的 one 对象。
将其替换为显式循环-而不是可变函数参数-它将为每个dict条目创建一个新对象:
for key in lengths:
lengths[key] = {}
print(id(lengths[0]), id(lengths[1]))
输出:
139872021765576 139872021765288
{0: {2: 1, 1: 1}, 1: {2: 1, 3: 1}}
现在您有了单独的对象。
如果您想要单线,请使用dict理解:
lengths = {key: {} for key in lengths}