Home > Mobile >  Append 1 for the first occurence of an item in list p that occurs in list s, and append 0 for the ot
Append 1 for the first occurence of an item in list p that occurs in list s, and append 0 for the ot

Time:05-27

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]
  • Related