Daniel Gebrahanus
Daniel Gebrahanus

Reputation: 223

zip argument #1 must support iteration error when looping through zip

I have seen few other similiar issues reported however I wasn't able to replicate that solution in my case.

My problem is bit more simpler as I have one list of numbers and one list of strings

number = [21, 44, 31, 553, 63, 35]
access = ["denied", "Try Again", "Retry", "Accepted", "Error", "Success"]

I have zipped them and created a pair with each value that looks like this

testInput = zip(number, access)

output: 
[(21, 'denied'), (44, 'Try Again'), (31, 'Retry'), (553, 'Accepted'), (63, 'Error'), (35, 'Success')]

I am trying to loop through each pair and execute my function that maps them to a team name based on the value of the pairs. Here was my attempt:

def mapping(number, access):
    team = ''
    checkNumberAndAccess = zip(number, access)
    for number, access in checkNumberAndAccess:
        if number in range(20,30):
            team = 'Revolt'
        elif (number in range(40,50)) and (access == 'Try Again'):
            team = 'Strike'
        elif (number in range(60,100)) and (access == 'Error'):
            team = 'Exception'
    print team
    return team

I want 'Team' variable to hold the value of the mapping output for each pair so this is where I am executing the function:

for number, access in testInput:
    Team = mapping(number, access)
    df = df.append({'Access Message': access, 'Number': number}, ignore_index=True)
print df

I get "TypeError: zip argument #1 must support iteration" error when executing the mapping function. Is it in the wrong place?

full code:

import pandas as pd

df = pd.DataFrame()


number = [21, 44, 31, 553, 63, 35]
access = ["denied", "Try Again", "Retry", "Accepted", "Error", "Success"]


def mapping(number, access):
    team = ''
    checkNumberAndAccess = zip(number, access)
    for number, access in checkNumberAndAccess:
        if number in range(20,30):
            team = 'Revolt'
        elif (number in range(40,50)) and (access == 'Try Again'):
            team = 'Strike'
        elif (number in range(60,100)) and (access == 'Error'):
            team = 'Exception'
    print team
    return team


testInput = zip(number, access)
print testInput

for number, access in testInput:
    Team = mapping(number, access)
    df = df.append({'Access Message': access, 'Number': number}, ignore_index=True)
print df

Upvotes: 3

Views: 10092

Answers (2)

jezrael
jezrael

Reputation: 863791

What about pandas solution?

number = [21, 44, 31, 553, 63, 35]
access = ["denied", "Try Again", "Retry", "Accepted", "Error", "Success"]

#create DataFrame
df = pd.DataFrame({'number':number, 'access':access})

#create boolean masks
m1 =  df['number'].isin(range(20,30))
m2 =  df['number'].isin(range(40,50)) & (df['access'] == 'Try Again')
m3 =  df['number'].isin(range(60,100)) & (df['access'] == 'Error')

#create new column by conditions
df['Access Message'] = np.select([m1, m2,m3], ['Revolt','Strike','Exception'], default='')
print (df)
      access  number Access Message
0     denied      21         Revolt
1  Try Again      44         Strike
2      Retry      31               
3   Accepted     553               
4      Error      63      Exception
5    Success      35               

In your solution is possible in loop append output to list and last create DataFrame by constructor:

number = [21, 44, 31, 553, 63, 35]
access = ["denied", "Try Again", "Retry", "Accepted", "Error", "Success"]

def mapping(number, access):
    out = []
    checkNumberAndAccess = zip(number, access)
    for number, access in checkNumberAndAccess:
        if number in range(20,30):
            out.append('Revolt')
        elif (number in range(40,50)) and (access == 'Try Again'):
            out.append('Strike')
        elif (number in range(60,100)) and (access == 'Error'):
            out.append('Exception')
        else:
            #add default value  
            out.append('')
    return out

access = mapping(number, access)

df = pd.DataFrame({'Access Message': access, 'Number': number})
print (df)
  Access Message  Number
0         Revolt      21
1         Strike      44
2                     31
3                    553
4      Exception      63
5                     35

Upvotes: 1

Saranya Sridharan
Saranya Sridharan

Reputation: 226

Try this .

import pandas as pd

df = pd.DataFrame()


number = [21, 44, 31, 553, 63, 35]
access = ["denied", "Try Again", "Retry", "Accepted", "Error", "Success"]


def mapping(number, access):
    team = ''

    if number in range(20,30):
        team = 'Revolt'
    elif (number in range(40,50)) and (access == 'Try Again'):
        team = 'Strike'
    elif (number in range(60,100)) and (access == 'Error'):
        team = 'Exception'
    print team
    return team


testInput = zip(number, access)
print testInput

for number, access in testInput:
    Team = mapping(number, access)
    df = df.append({'Access Message': access, 'Number': number}, ignore_index=True)
print df

Or you can pass the total list from here and zip there , process and return the final result to the calling function.Hope this helps

Upvotes: 0

Related Questions