#πŸ”’ List formatting problem I can't solve (beginner programmer)

103 messages Β· Page 1 of 1 (latest)

turbid wadi
#

hi guys, super beginner programmer so noob question, I have a list of strings alternating numbers and numbers+" bpm"(eg: ['123123','123123 bpm','123123','1231231 bpm']) I am trying to remove all the " bpm" from the odd-indexed strings then convert every element of the list from a string into a float when there's only numbers left. However my brain is about to explode and I'm not making any progress, Can someone help me with this code?
Code:

indexCounter = 0
for el in list:
    if indexCounter%2==1:
        list[indexCounter]=list[el[:-4]]
    list[indexCounter]=float(el)
    indexCounter += 1

I am returned with TypeError: list indices must be integers or slices, not str

dusky summitBOT
#

@turbid wadi

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

severe vault
#

if you want to modify the original list you might need to use a range-based for loop

#

!e

elements = ["1", "1 bpm", "2", "2 bpm"]
for i in range(len(elements)):
    element = elements[i]
    if "bpm" in element:
        elements[i] = float(element[0:element.index("bpm")].strip())
    else:
        elements[i] = float(element)
print(elements)
dusky summitBOT
feral rock
#

if this is a beginner problem i am less than a stick

turbid wadi
severe vault
#

also not "100 bpm"

turbid wadi
#

also could you explain why the ranged-based for loop is necessary? compared to just a normal for loop? is it just to have the index counter integrated?

severe vault
#

if you're making a new list then you can use that kind of loop

turbid wadi
#

I see..

ivory terrace
severe vault
#

difference is you're iterating over a range instead of the list itself

turbid wadi
#

!e

elements = ["1", "1 bpm", "2", "2 bpm, 2, 2 bpm"]
for i in range(len(elements)):
    element = elements[i]
    if "bpm" in element:
        elements[i] = float(element[0:element.index("bpm")].strip())
    else:
        elements[i] = float(element)
print(elements)
dusky summitBOT
severe vault
#

usually you don't want to modify the object you're iterating over

turbid wadi
#

oof, duplicates are an issue

#

I'm assuming the duplicates dont work because when it calls elements[i] it calls the first accessed only?

#

so in that case, should I use a separate counter instead that goes up after every iteration to forcibly call the next in the index?

severe vault
turbid wadi
#

but still iterate through them too

severe vault
turbid wadi
#

but it output only 4 elements instead of the 6 in the list

#

so I was assuming that it didnt work for duplicates

#

oh wait no did IU just not type in the quotations? wait lemme try that again

#

!e

elements = ["1", "1 bpm", "2", "2 bpm", "2", "2 bpm"]
for i in range(len(elements)):
    element = elements[i]
    if "bpm" in element:
        elements[i] = float(element[0:element.index("bpm")].strip())
    else:
        elements[i] = float(element)
print(elements)
dusky summitBOT
turbid wadi
#

okay nvm

#

I'm jsut slow

#

😭

severe vault
#

like while "bpm" in element:

#

and then slice using the index of each "bpm"

turbid wadi
#

haha

severe vault
#

alright cool

normal tide
#

!e

elements = ["1", "1 bpm", "2", "2 bpm", "2", "2 bpm"]

print([float(element.split()[0]) for element in elements])
dusky summitBOT
severe vault
#

why didn't i think of split...

normal tide
#

That should work for 1 or more white spaces I think

turbid wadi
normal tide
#

.split() splits a string on white space by deafult, in this list comphrension we're just taking the first element which happens to be our numbers

severe vault
normal tide
#

!e

print([float(ele.split()[0]) for ele in ['123123','123123 bpm','123123','1231231 bpm']])
dusky summitBOT
turbid wadi
#

so to store it back in the original list it'd be this?

elements[element] = [float(element.split()[0]) for element in elements]
print(elements)
#

!e

elements[element] = [float(element.split()[0]) for element in elements]
print(elements)
dusky summitBOT
turbid wadi
#

oh forgot to put the list in

#

!e

elements = ["1", "1 bpm", "2", "2 bpm", "2", "2 bpm"]
elements[element] = [float(element.split()[0]) for element in elements]
print(elements)
dusky summitBOT
turbid wadi
#

I-

normal tide
#

It's a really good idea to just create a brand new list instead of trying to update or overwrite the old one. This is true for a lot of objects because mutable things are very hard to keep track of compared to dealing with things as if they are immutable

turbid wadi
#

ohh it can't read tthat because I haven't initialized element yet

#

and I'm calling it

turbid wadi
#

!e

elements = ["1", "1 bpm", "2", "2 bpm", "2", "2 bpm"]
newElements = [float(element.split()[0]) for element in elements]
print(elements)
dusky summitBOT
turbid wadi
#

!e

elements = ["1", "1 bpm", "2", "2 bpm", "2", "2 bpm"]
newElements = [float(element.split()[0]) for element in elements]
print(newElements)
dusky summitBOT
turbid wadi
#

like that?

normal tide
#

Yes exactly, try and use snake_case since this is Python and give it a good enough name so you know what you've got there and that's perfect

#

!e

bpms = ['123123','123123 bpm','123123','1231231 bpm']

processed_bpms = [float(ele.split()[0]) for ele in bpms]

print(processed_bpms)
dusky summitBOT
turbid wadi
normal tide
#

Just try to keep your future self in mind when naming things, all devs spend more time reading code then they do writing it so make it easier to read every chance you get

turbid wadi
#

okay, so followup question

#

I now need to group them in 2s and write it out into a txt file where inside it would just be a long string of characters like this: 67.12|69,90|1500 with every element grouped with other element. so for that example the original string would have been:

['69','67.12 bpm','90','1500 bpm']
#

oh god

#

I just realized this small program I thought would take me 30 mins

#

is a lot harder than I expected

#

WHY IS THE ORDER THE OTHER WAY AROUND

#

omg

#

so I'm assuming, iterate through list, split odd from even indices, and then put them back except the odd ones first instead of the even ones to get a list with the right order, but now I just need to know how to write it out into a txt file

#

as a long string with "|" in the middle of each instead of commas

ivory terrace
#

(or it has to do with readability but but that doesn't mean that other styles aren't just as readable)

normal tide
#

There is an easy enough way to take pairs of elements from a list, let me see if I can recall it

#
def pair_off(lst):
    """
    Takes a 1D list and returns a list of tuples of the items in the list paired off.

    Parameters:
    lst (list): The input list.

    Returns:
    list: A list of tuples with paired items.
    """
    return [(lst[i], lst[i + 1]) for i in range(0, len(lst) - 1, 2)]
turbid wadi
#

def paired_list(lst):
    return [(lst [i+1], lst[i]) for i in range(0, len(lst) - 1,2)]

ultraProcessedBPMS = paired_list(processed_bpms)
print(ultraProcessedBPMS)


#

so like that?

normal tide
#

!e

def pair_off(lst):
    return [(lst[i], lst[i + 1]) for i in range(0, len(lst) - 1, 2)]

def clean_bpms(bpms):
    return [float(ele.split()[0]) for ele in bpms]

bpms = ['69','67.12 bpm','90','1500 bpm']

strings_to_concat = [f"{pair[0]}|{pair[1]}" for pair in pair_off(clean_bpms(bpms))]

strings_to_concat

final_string = ",".join(strings_to_concat)

print(final_string)
dusky summitBOT
normal tide
#

yeah something like paired_bpms would probably be fine if you know the flow of your code. Once names get too long they also become hard to read and understand

#

There might also be a csv writer that Python has to help with writing this list of strings to a file versus creating one big string to write.

#

If you want to be really efficient there is always converting the list comphrensions into generators instead but I don't know what scale you're working on.

turbid wadi
normal tide
#

Yeah that could work depending on the scale, there are other ways to write it if you know it's going to be a csv

# Example data
header = ['Name', 'Age', 'City']
data = [
    ['Alice', 30, 'New York'],
    ['Bob', 25, 'Los Angeles'],
    ['Charlie', 35, 'Chicago']
]

with open('output.csv', 'w', newline='') as file:
    writer = csv.writer(file)
    writer.writerow(header)  # Write the header
    writer.writerows(data)   # Write the data
#

If your project is small enough you can probably hold the whole string in memory and just go about writing it that way, if you're dealing with a LOT of data then using generators and the csv writer to write rows as they become available is probably the very best way to do it.

#

You'll have to decide what you need for your project

turbid wadi
#

OMG IT WORKS

#

YOU GUYS ARE GODS AMONGST MEN

#

THANK YOU

#

πŸ’•

#

!close

dusky summitBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.