为列表 p 中出现在列表 s 中的项目的第一次出现追加 1,并为其他出现和 s 中的其他项目追加 0
Append 1 for the first occurence of an item in list p that occurs in list s, and append 0 for the other occurence and other items in s
我希望此代码为列表 p 中出现在列表 s 中的项目的第一次出现附加 1,并为其他出现和 s 中的其他项目附加 0。
下面是我当前的代码,它为所有出现的事件附加 1,我希望它仅为第一次出现的事件附加 1。求助
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
bin = []
for i in s:
if i in p:
bin.append(1)
else:
bin.append(0)
print(bin)
# current result [0, 0, 1, 0, 1, 1, 0, 0, 0, 1]
# excepted result [0, 0, 1, 0, 1, 0, 0, 0, 0, 0]
最简单的解决方案是从列表中删除项目 p
如果找到:
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
out = []
for i in s:
if i in p:
out.append(1)
p.remove(i)
else:
out.append(0)
print(out)
打印:
[0, 0, 1, 0, 1, 0, 0, 0, 0, 0]
使用 index
查找列表中的第一个匹配项。
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
bin = [0] * len(s)
for value in p:
bin[s.index(value)] = 1
看过一次的元素一定要记得。为此使用一套。
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
bin = []
seen = set()
for i in s:
if i in p:
if i in seen:
bin.append(0)
else:
bin.append(1)
seen.add(i)
else:
bin.append(0)
print(bin)
结果是[0, 0, 1, 0, 1, 0, 0, 0, 0, 0]
这只会遍历数据一次,不会修改任何输入值。
循环的压缩版本:
for i in s:
if i in p and i not in seen:
bin.append(1)
seen.add(i)
else:
bin.append(0)
正如一些正确指出的那样,一些解决方案更改了 s
和 p
,因此 re-runs 不一致。所以要小心。
我会用一个很好的方法包装它:
import copy
def mark_first_key_occurence(values, keys):
def account_for(v, c):
if v not in c:
return 0
c.remove(v)
return 1
keys_copy = copy.deepcopy(keys)
return [account_for(v, keys_copy) for v in values]
然后调用它:
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
print(mark_first_key_occurence(s, p))
更新:毫无疑问,凯利的解决方案是最好的。列表没有带有默认值的类似于 pop
的方法,但使用字典绝对是一个巧妙的技巧! 请感谢他。
这是我的小改动(我认为明确调用 pop
更干净)
d = dict.fromkeys(p, 1)
print([d.pop(i, 0) for i in s])
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
bin = [0]*len(s) # let the array contain only 0
for i in p: # for each element in p
flag = False # this flag is made to true if the first occurence has been set to 1 in the bin array
for j in range(len(s)):
if((s[j]==i) and (not flag)):
bin[j] = 1
flag = True
print(bin)
更优雅的方式:
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
bin = [1 if x in p else 0 for x in s]
idxs = [idx for idx, item in enumerate(s) if item in s[:idx]]
for idx in idxs:
bin [idx] = 0
print(bin)
[0, 0, 1, 0, 1, 0, 0, 0, 0, 0]
O(|s|+|p|) 时间并且不修改输入:(Try it online!):
d = dict.fromkeys(p, 1).pop
bin = [d(i, 0) for i in s]
我希望此代码为列表 p 中出现在列表 s 中的项目的第一次出现附加 1,并为其他出现和 s 中的其他项目附加 0。
下面是我当前的代码,它为所有出现的事件附加 1,我希望它仅为第一次出现的事件附加 1。求助
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
bin = []
for i in s:
if i in p:
bin.append(1)
else:
bin.append(0)
print(bin)
# current result [0, 0, 1, 0, 1, 1, 0, 0, 0, 1]
# excepted result [0, 0, 1, 0, 1, 0, 0, 0, 0, 0]
最简单的解决方案是从列表中删除项目 p
如果找到:
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
out = []
for i in s:
if i in p:
out.append(1)
p.remove(i)
else:
out.append(0)
print(out)
打印:
[0, 0, 1, 0, 1, 0, 0, 0, 0, 0]
使用 index
查找列表中的第一个匹配项。
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
bin = [0] * len(s)
for value in p:
bin[s.index(value)] = 1
看过一次的元素一定要记得。为此使用一套。
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
bin = []
seen = set()
for i in s:
if i in p:
if i in seen:
bin.append(0)
else:
bin.append(1)
seen.add(i)
else:
bin.append(0)
print(bin)
结果是[0, 0, 1, 0, 1, 0, 0, 0, 0, 0]
这只会遍历数据一次,不会修改任何输入值。
循环的压缩版本:
for i in s:
if i in p and i not in seen:
bin.append(1)
seen.add(i)
else:
bin.append(0)
正如一些正确指出的那样,一些解决方案更改了 s
和 p
,因此 re-runs 不一致。所以要小心。
我会用一个很好的方法包装它:
import copy
def mark_first_key_occurence(values, keys):
def account_for(v, c):
if v not in c:
return 0
c.remove(v)
return 1
keys_copy = copy.deepcopy(keys)
return [account_for(v, keys_copy) for v in values]
然后调用它:
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
print(mark_first_key_occurence(s, p))
更新:毫无疑问,凯利的解决方案是最好的。列表没有带有默认值的类似于 pop
的方法,但使用字典绝对是一个巧妙的技巧! 请感谢他。
这是我的小改动(我认为明确调用 pop
更干净)
d = dict.fromkeys(p, 1)
print([d.pop(i, 0) for i in s])
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
bin = [0]*len(s) # let the array contain only 0
for i in p: # for each element in p
flag = False # this flag is made to true if the first occurence has been set to 1 in the bin array
for j in range(len(s)):
if((s[j]==i) and (not flag)):
bin[j] = 1
flag = True
print(bin)
更优雅的方式:
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
bin = [1 if x in p else 0 for x in s]
idxs = [idx for idx, item in enumerate(s) if item in s[:idx]]
for idx in idxs:
bin [idx] = 0
print(bin)
[0, 0, 1, 0, 1, 0, 0, 0, 0, 0]
O(|s|+|p|) 时间并且不修改输入:(Try it online!):
d = dict.fromkeys(p, 1).pop
bin = [d(i, 0) for i in s]