In a list, 1 if it fulfills condition 1, 0 if it fulfills condition 2, ignore it if it does not fulfill both

Viewed 68

I have a list like this now.

gen = ["f", 'M', "female", "Male", "male", "F", "m", "m", "male", "Female", "x"]

As their may be different input formats, female may appear as "F", "f", "Female", or "female", and male may appear as "M", "m", "Male", or "male" in the list. How can we turn the list into a new gender list called "gen2" with only 0s and 1s, with 0 representing females, and 1 representing males. If there is any other elements in the list, just assume it as invalid and simply ignore it in the new list?

I tried this:

n=0
gen2=[]
for i in gen:
    s=print(gen[n][0]==str.lower('F'))
    if s is True:
        gen2.append(0)
        n=n+1
    elif s is False:
        gen2.append(1)
        n=n+1

print(gen2)

and the expected output will be

[0, 1, 0, 1, 1, 0, 1, 1, 1, 0]
4 Answers
gen2=[]
for i in gen:
    if i[0].lower() == "f":
        gen2.append(0)
    else:
        gen2.append(1)

print(gen2)

print always returns None--it's not suitable for use in logic like this. Also, there's no need for n and i--you already have the element with i (probably only use i for indices, though--prefer s, x or e to represent an arbitrary element in a list).

You could use a small lookup table that performs the conversions, then filter and translate in a list comprehension:

>>> gender_to_binary = dict(m=1, M=1, f=0, F=0)
>>> [gender_to_binary[x[0]] for x in gen if x and x[0] in gender_to_binary]
[0, 1, 0, 1, 1, 0, 1, 1, 1, 0]

if x protects against empty iterables (there's almost never a need for foo is True, just foo is sufficient and reads cleanly).

If your logic is that the match must be exact on "m"/"male"/"f"/"female" case insensitively, this is more precise:

>>> gender_to_binary = dict(m=1, male=1, f=0, female=0)
>>> [gender_to_binary[x.lower()] for x in gen if x.lower() in gender_to_binary]
[0, 1, 0, 1, 1, 0, 1, 1, 1, 0]

This can be easily answered with this code

gen = ["f", 'M', "female", "Male", "male", "F", "m", "m", "male", "Female", "x"]
gen2=[]
for i in gen:
    print(i.lower())
    if i.lower() == 'f' or i.lower() == 'female':
        gen2.append(0)
    elif i.lower() == 'm' or i.lower() == 'male':
        gen2.append(1)
print(gen2)

It's not the efficient method but you can use two list comprehensions

gen = ["f", 'M', "female", "Male", "male", "F", "m", "m", "male", "Female", "x","y"]

a=[0  if x.lower().startswith('f') else 1 if x.lower().startswith('m') else None for x in gen]
[i for i in a if i != None]

using if, else if and else in list comprehension. using string methods lower and startswith and in 2nd list comprehension removing the None items. Output:

[0, 1, 0, 1, 1, 0, 1, 1, 1, 0]
Related