Corey
Corey

Reputation: 133

TypeError: Must be String, not list

I'm sure this is already posted somewhere between StackOverflow and Google but I am unable to find the solution because I don't know the exact terms to search.

I'm going to try to be as specific as possible. I have a bunch of zip files with with reports inside of them with names like Process123456789results.csv. I need to rename the CSV file to the name of its parent ZIP folder.

So for ease of understanding I need to turn this:

Into this:

To do that I am using ZipFile, my script looks a bit like this (very inexperienced programmer here so all criticism is welcome):

Extracted = []
x = 0

for attachment in zip:
with zipfile.ZipFile("IntendedName.zip", "r") as z:
    z.extractall()
    Extracted = [z.namelist()]
    os.rename(Extracted[x], "IntendedName.csv")
os.remove("IntendedName.zip")
x +=1

Ideally the end result will be:

  1. Extract the CSV

  2. Rename the CSV to the ZIP files name.

  3. Cleanup the zip file leaving only the renamed CSV.

My issues:

  1. Running my code I am given the following error must be string, not list. I've tried approaching this from a couple different angles but can't quite get around this. I know it's not the same thing but I was reading about "typecasting" in C. Is there something similar I can do here? I was going to get a list of all names and export it to a text file and use that..But that feels like a dirty way to tackle this.

  2. I don't know if this will be an issue but using a debugger I can see the value of "Extracted" ends up looking like this: [u'Process123456789results.csv'] when it's called from z.namelist() which I think (unconfirmed) will break the the script after number 1 is fixed because when I try to rename the file it will be unable to find a file by the bold name above instead of just "Process123456789results.csv". Is it possible to modify a list by just deleting the extraneous characters? This could just be me over thinking this. I don't even know if this is a problem because I can't get passed the issue stated above.

I apologize if I have been unclear about something. I'll do my best to answer any questions. I can post the entire code I am working on if it will help. It's not exactly pretty, though.

SOLUTION:

After getting some direction I was able to figure out how to tackle this. The issue I was talking about in number 2 above never became an issue. Number 1 was resolved by some very helpful individuals below.

The "index out of error" issue I mentioned in the comments to Shank was resolved with the following code:

Extracted = []
x = 0

for attachment in zip:
with zipfile.ZipFile("IntendedName.zip", "r") as z:
    z.extractall()
    Extracted.extend(z.namelist())
    os.rename(Extracted[x], "IntendedName.csv")
os.remove("IntendedName.zip")
x +=1

Edit: Removed redundant parenthesis. Edit again: Added a completed solution. Thanks for the help guys!

Upvotes: 3

Views: 4417

Answers (2)

Shashank
Shashank

Reputation: 13869

For os.rename(Extracted[x], "IntendedName.csv"), Extracted[0] seems to be pointing to a list of names. If you want to iterate through the namelist, just have your assignment be Extracted = z.namelist(). When you do Extracted = [z.namelist()], it wraps a list within a list, so when you access the 0 index element to pass it into os.rename, you're actually passing in a list as the first parameter, not a string as it expects.

Upvotes: 1

mipadi
mipadi

Reputation: 411290

I believe the issue is this line:

Extracted = [z.namelist()]

I'm guessing namelist() already returns a list, so you're putting a list inside a list. I think you meant this instead:

Extracted = z.namelist()

Upvotes: 0

Related Questions