Counting like elements in a list and appending list
Question: I am trying to create a `list` in `Python` with values pulled from an active
`excel` sheet. I want it to pull the step # value from the excel file and
append it to the list while also including which number of that element it is.
For example, `1_1` the first time it pulls 1, `1_2` the second time, `1_3` the
third, etc. My code is as follows...

    
    
    import win32com.client
    xl = win32com.client.Dispatch("Excel.Application")
    CellNum = xl.ActiveSheet.UsedRange.Rows.Count
    Steps = []
    for i in range(2,CellNum + 1):  #Create load and step arrays in abaqus after importing from excel
    if str(int(xl.Cells(i,1).value))+('_1' or '_2' or '_3' or '_4' or '_5' or '_6') in Steps:
        StepCount = 1
        for x in Steps:
            if x == str(int(xl.Cells(i,1).value))+('_1' or '_2' or '_3' or '_4' or '_5' or '_6'):
                StepCount+=1
        Steps.append(str(int(xl.Cells(i,1).value))+'_'+str(StepCount))
    else:
        Steps.append(str(int(xl.Cells(i,1).value))+'_1')
    

I understand that without the excel file, the program will not run for any of
you, but I was just wondering if it is some simple error that I am missing.
When I run this, the StepCount does not go higher than 2 so I receive a bunch
of 1_2, 2_2, 3_2, etc elements. I've posted my resulting list below.

    
    
    >>> Steps
    ['1_1', '2_1', '3_1', '4_1', '5_1', '6_1', '7_1', '8_1', '9_1', '10_1', '11_1', '12_1',
     '13_1', '14_1', '1_2', '14_2', '13_2', '12_2', '11_2', '10_2', '2_2', '3_2', '9_2',
     '8_2', '7_2', '6_2', '5_2', '4_2', '3_2', '2_2', '1_2', '2_2', '3_2', '4_2', '5_2', 
    '6_2', '7_2', '8_2', '9_2', '10_2', '11_2', '12_2', '13_2', '14_2', '1_2', '2_2']
    

**EDIT #1:** So, if the `('_1' or '_2' or '_3' or '_4' or '_5' or '_6')` will
ALWAYS only use _1, is it this line of code that is messing with my counter?

    
    
    if x == str(int(xl.Cells(i,1).value))+('_1' or '_2' or '_3' or '_4' or '_5' or '_6'):
    

Since it is only using `_1`, it will only count `1_1` and not check `1_2, 1_3,
1_4, etc`

**EDIT #2:** Now I am using the following code. My input list is also below.

    
    
    from collections import defaultdict
    StepsList = []
    Steps = []
    tracker = defaultdict(int)
    
    for i in range(2,CellNum + 1):
        StepsList.append(int(xl.Cells(i,1).value))
    
    >>> StepsList
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 14, 13, 12, 11, 10, 2, 3, 9, 8,
     7, 6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1, 2]
    
    for cell in StepsList:
        Steps.append('{}_{}'.format(cell, tracker[cell]+1)) # This is +1 because the     tracker starts at 0
        tracker[cell]+=1
    

I get the following error: `ValueError: zero length field name in format` from
the `for cell in StepsList:` iteration block

**EDIT #3:** Got it working. For some reason it didn't like

    
    
    Steps.append('{}_{}'.format(cell, tracker[cell]+1))
    

So I just changed it to

    
    
    for cell in StepsList:
        tracker[cell]+=1
        Steps.append(str(cell)+'_'+str(tracker[cell]))
    

Thanks for all of your help!


Answer: This line:

    
    
    if str(int(xl.Cells(i,1).value))+('_1' or '_2' or '_3' or '_4' or '_5' or '_6') in Steps:
    

does not do what you think it does. `('_1' or '_2' or '_3' or '_4' or '_5' or
'_6')` will _always_ return `'_1'`. It does not iterate over that series of
`or` values looking for a match.

Without seeing expected input vs. expected output, it's hard to point you in
the correct direction to actually get what you want out of your code, but
likely you'll want to leverage
[`itertools.product`](https://docs.python.org/2/library/itertools.html#itertools.product)
or one of the other combinatoric methods from `itertools`.

**Update**

Based on your comments, I think that this is a way of solving your problem.
Assuming an input list of the following:

    
    
    in_list = [1, 1, 1, 2, 3, 3, 4]
    

You can do the following:

    
    
    from collections import defaultdict
    
    tracker = defaultdict(int) # defaultdict is just a regular dict with a default value at new keys (in this case 0)
    steps   = []
    
    for cell in in_list:
        steps.append('{}_{}'.format(cell, tracker[cell]+1)) # This is +1 because the tracker starts at 0
        tracker[cell]+=1
    

Result:

    
    
     >>> steps
     ['1_1', '1_2', '1_3', '2_1', '3_1', '3_2', '4_1']
    

There are likely more efficient ways to do this using combinations of
`itertools`, but this way is certainly the most straight-forward

