I want this code to 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.
That's my current code below and it is appending 1 for all occurences, I want it to append 1 for the first occurence alone. Please, help
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]
CodePudding user response:
The simplest solution is to remove the item from list p
if found:
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)
Prints:
[0, 0, 1, 0, 1, 0, 0, 0, 0, 0]
CodePudding user response:
Use index
to find the first occurrence in a list.
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
CodePudding user response:
You have to remember if you have seen the element once. Use a set for that.
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)
The result is [0, 0, 1, 0, 1, 0, 0, 0, 0, 0]
This runs over the data only once and doesn't modify any of the input values.
A compressed version of the loop:
for i in s:
if i in p and i not in seen:
bin.append(1)
seen.add(i)
else:
bin.append(0)
CodePudding user response:
As some correctly pointed out, some of the solutions change s
and p
, hence re-runs are inconsistent.
I would wrap this using a nice method:
def mark_first_key_occurence(values, keys):
def account_for(v, c):
if v not in c:
return 0
p.remove(v)
return 1
return [account_for(v, keys) for v in values]
Then call it using:
s = [20, 39, 0, 87, 13, 0, 23, 56, 12, 13]
p = [0, 13]
print(mark_first_key_occurence(s, p))
CodePudding user response:
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)
CodePudding user response:
More elegant way:
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]