How to write list elements into a tab-separated file?

13,545

Solution 1

I think you're doing a list comprehension over the list inside of the dictionary. An alternative solution would be

with open('fname', 'w') as file:
    for nested_list in dict_with_lists.values():
        for word in nested_list:
             file.write(word + '\t')
         file.write('\n')

\I'm just looping over the values of the dictionaries, which are lists in this case and joining them using a tab and writing a newline at the end of each list. I haven't tested it but theoretically I think it should work.

Solution 2

If nested_list is one of your dictionary values, then you are applying '\t'.join() to the individual words. You'd want to join the whole list:

file.write('\t'.join(nested_list) + '\n')

or, if you were to loop over the values of the dictionary:

file.writelines(
    '\t'.join(nested_list) + '\n'
    for nested_list in dict_with_lists.values())

The above uses the file.writelines() method correctly; passing in an iterable of strings to write. If you were to pass in a single string, then you are only causing Python extra work as it loops over all the individual characters of that string to write those separately, after which the underlying buffer has to assemble those back into bigger strings again.

However, there is no need to re-invent the character-separated-values writing wheel here. Use the csv module, setting the delimiter to '\t':

import csv

with open('fname', 'w', newline='') as file:
    writer = csv.writer(file, delimiter='\t')
    writer.writerows(dict_with_lists.values())

The above writes all lists in the dict_with_lists dictionary to a file. The csv.writer() object doesn't mind if your lists are of differing lengths.

Solution 3

You need to turn each list value in the dictionary into a string of tab-separated values that also have a '\n' newline character at the end of each one of them:

value1, value2 = 'key1', 'key2'
dict_with_lists = {}
dict_with_lists[value1] = ['word1', 'word2', 'word3', 'word4']
dict_with_lists[value2] = ['word1', 'word2', 'word3']

fname = 'dict_list_values.tsv'

with open(fname, 'w') as file:
    file.writelines(
        '\t'.join(values)+'\n' for values in dict_with_lists.values()
    )
Share:
13,545

Related videos on Youtube

Anastasia
Author by

Anastasia

Updated on June 04, 2022

Comments

  • Anastasia
    Anastasia almost 2 years

    I have searched the web but I haven't found the answer for my problem:

    I have a a dictionary with lists as elements and every list has a different length. For example like that:

    dict_with_lists[value1] = [word1, word2, word3, word4]
    dict_with_lists[value2] = [word1, word2, word3]
    

    My main problem is, that I want to write the list elements in to a file which should be tab-separated and if the list is finished it should write the new list in a new line.

    I found a solution like that:

    with open('fname', 'w') as file:
       file.writelines('\t'.join(i) + '\n' for i in nested_list)
    

    But it doesn't only separate the words with tabs but also the characters.

    • Martijn Pieters
      Martijn Pieters almost 6 years
      How is dict_with_lists related to nested_list?
    • Martijn Pieters
      Martijn Pieters almost 6 years
      Also, in what order should those dictionary values be written? Is the key involved anywhere at all?
    • W4t3randWind
      W4t3randWind almost 6 years
      "But it doesn't only separate the words with tabs but also the characters" This is a really terse sentence. Please rewrite this. Also, the issue with the file.writelines above is that i will necessarily be the key of your dictionary, not the list.
  • mad_
    mad_ almost 6 years
    Well it should work unless order of list is the concern
  • King
    King almost 6 years
    Agreed, but I don't think he listed order as a concern so I just went with the most straightforward way that's also similar to what he already had.
  • King
    King almost 6 years
    No problem, I'm really glad that I could help! :)
  • Martijn Pieters
    Martijn Pieters almost 6 years
    Sure, but it's not clear if the OP wants the whole dictionary retained anyway.
  • Anastasia
    Anastasia almost 6 years
    I just read that the order isn't contained, is it possible to keep it? Also I noticed that I need to add the value for each list also to the beginning of the line, how should I change the code to also work for that case? The value is triple like (v1,v2,v3). I'm sorry I didn't clearify that earlier! @King
  • King
    King almost 6 years
    You could do another for loop since it preserves order for you and just write each word then write a new line, just edited my answer. How's that @Anastasia
  • Anastasia
    Anastasia almost 6 years
    It works, thank you again! :D But now I'm not sure how to access the value of the dictionary and I tried out some options myself but it didn't kinda work... Sorry again for another question!
  • King
    King almost 6 years
    What do you mean by access the value of the dictionary? If you'd like a list of the keys, then you can simply use dict_with_lists.keys(), this will return a list of keys from your dict.
  • Anastasia
    Anastasia almost 6 years
    haha I'm so sorry I'm stupid I confused the names... :D thank you again! :)
  • King
    King almost 6 years
    You're not stupid, we all make mistakes and you're welcome. I'm overjoyed that I was able to help you. People here can be a little mean sometimes and it scares people off.