0

I have a dataframe of lists that look like this:

alist = ['male','male', 'male','female','male, '0', 'female','female','female','male', 'female']
        ['0','female', 'male','female','female, 'male', 'male','male','female','male',]

Now, i want to set all 'male' values nested between 'females' to zero, and vice versa, so as to have a list of non-overlapping values.

['male','male', 'male','0','male, '0', 'female','female','female','0', 'female']
['0','female', '0','female','female, 'male', 'male','male','0','male',]

I have tried this:

 for i in alist:
        rules1 = [ i == 'male',   
             i + 1 == 'female',
              i - 1 == 'female']
        rules2 = [ i == 'female',   
             i + 1 == 'male',
              i - 1 == 'male']
        if all(rules1) or all(rules2):
            i = 0
        else:
            i = i
    return alist   

fixlist_['new_tags'] = fixlist_.apply(find_start, axis=1)       

I am doing something wrong, but i cant seem to catch it. this code returns an error

----> 9              i + 1 == 'cons',
     10               i - 1 == 'cons']
     11         rules2 = [ i == 'cons',   

TypeError: ('can only concatenate str (not "int") to str', 'occurred at index 0')

Thanks all.

kay fresh
  • 121
  • 2
  • 10
  • 1
    The first error I encountered is the missing quote after 4th `male` in the list. And your `i` is not an index, it’s a value of the list like `'male'` etc. This is the reason for your TypeError. – Melebius May 12 '20 at 12:52
  • 1
    Does this answer your question? [Python loop that also accesses previous and next values](https://stackoverflow.com/questions/1011938/python-loop-that-also-accesses-previous-and-next-values) – Melebius May 12 '20 at 12:52
  • @Melebius The link was helpful, but below is a precise solution – kay fresh May 12 '20 at 13:20

3 Answers3

1

You can try this:

for i, value in enumerate(alist):
    if i>1 and i<len(alist)-1 and value == 'male' and alist[i-1] == 'female' and alist[i+1] == 'female':
        alist[i] = '0'
    if i>1 and i<len(alist)-1 and value == 'female' and alist[i-1] == 'male' and alist[i+1] == 'male':
        alist[i] = '0'
print(alist)

['male', 'male', 'male', '0', 'male', '0', 'female', 'female', 'female', '0', 'female', '0', 'female', '0', 'female', 'female', 'male', 'male', 'male', '0', 'male']
NYC Coder
  • 7,424
  • 2
  • 11
  • 24
1

I don't think there is any code syntax in python like this

rules1 = [ i == 'male',   
             i + 1 == 'female',
              i - 1 == 'female']

the below code would work

for pos, element in enumerate(alist):

    if pos == 0 and (pos == len(alist)-1):
        continue

    if element == 'male' and alist[pos-1] == 'female' and alist[pos+1] == 'female':
        alist[pos] = 0
        continue

    if element == 'female' and alist[pos-1] == 'male' and alist[pos+1] == 'male':
        alist[pos] = 0
Jis Mathew
  • 175
  • 1
  • 7
1
new_list = []

for i, element in enumerate(alist):
    if i > 0 and i < len(alist)-1:
        match_nested_male_rule = all([element=="male", alist[i-1]=="female", alist[i+1]=="female"])
        match_nested_female_rule = all([element=="female", alist[i-1]=="male", alist[i+1]=="male"])

        if any([match_nested_male_rule, match_nested_female_rule]):
            new_list.append("0")
            continue
    new_list.append(element)

print(new_list)

You don't need to create a new list, can replace element in the original list instead.

wei
  • 4,267
  • 2
  • 23
  • 18