8

I have a list of tuples in the format:

("some string", "string symbol", some number)

For example, ("Apples", "=", 10). I need to write them into the output file, like this:

Apples = 10

I'm having trouble with the write method. How can it be done?

Thanatos
  • 42,585
  • 14
  • 91
  • 146

6 Answers6

19

You can use:

for t in some_list:
  f.write(' '.join(str(s) for s in t) + '\n')

where f is your file.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
11
list_of_tuples = [('Apples', '=', 10), ('Oranges', '<', 20)]
f = open('file.txt', 'w')
for t in list_of_tuples:
    line = ' '.join(str(x) for x in t)
    f.write(line + '\n')
f.close()

Given a list of tuples, you open a file in write mode. For each tuple in the list, you convert all of its elements into strings, join them by spaces to form the string, and write the string with a new line to the file. Then you close the file.

Edit: Didn't realize you started off with a list of tuples. Made changes to reflect that.

JBernardo
  • 32,262
  • 10
  • 90
  • 115
U-DON
  • 2,102
  • 14
  • 14
  • 2
    Just `map(str, t)` — drop the lambda. – Thanatos Dec 03 '11 at 07:43
  • 2
    No need for lambda here. List comprehension is best practice and if you must use map, just use the built-in `str` as in `' '.join(map(str,t))` – Kenan Banks Dec 03 '11 at 07:43
  • Thanks, forgot you could put just the function. Also changed to a comprehension. – U-DON Dec 03 '11 at 07:45
  • 2
    @U-DON If you use ``[str(x) for x in t]`` or ``map(str,t)`` , you create a list object for each line to write. But **join()** method accepts a generator as argument: ``' '.join((str(x) for x in t))`` and in this case, the parens of the generator can be omitted : ``' '.join(str(x) for x in t)`` – eyquem Dec 03 '11 at 08:37
2
>>> data= ("Apples", "=", 10)
>>> print " ".join(map(str, data))
Apples = 10

Easy. Map the tuple/list to strings, then join them with " ".

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194
1
lot = [('Apples', '=', 10),
       ('Oranges', '<', 20),
       ('Peaches','(Florida)','No stock')]

with open('tototo.txt','w') as f:
    f.write( '\n'.join(' '.join(str(x) for x in tu) for tu in lot) )

Creating the entire text before writing it makes the writing in one pass.
Provided that the text isn't 25 GB long....

Note that on Windows, if the mode is 'w' , the OS will write \r\n each time it must write a \n;
If you want just \n to be written, you must define the mode as 'rb'

PS

It is 'wb' , not rb'

Edit 1

When Python writes on disk in 'w' mode on Windows, the operating system Windows writes \r\n sequences as ends of lines when it has lines to write on a disk, and when it has to write strings containing newlines, whatever are these newlines, \n alone or \r\n

If, for any personal whim, or curiosity, or religious conviction, or as a symptom of somnambulism, or to impress your wife, or to please your capricious kid, or because of a psychopath ghost living in your computer and shrieking each time an orthodox \r\n newline is written on disk, or simply because your algorithm requires it ...... yes, it may happen that you want to write only a newline as \n on a disk.... that's not science-fiction, it may REALLY happen, you now..... it happened to me, yes believe me or not , I was faced to the fact I was obliged to write a \n alone on a disk on Windows, without any nihil obstat and complementary imprimatur from some pythonist pope ! .... well, yes it may happen, and then, after having locked your seat-belt, you CAN, yes we can, write a newline \n on a disk on Windows ! Yes yes yes, it is possible and not a cause of damnation

Then , only in one of these cases, and if you have the legal age and all your mental capacities, and having drunk no beer nor wine in excess, you can use 'wb' to write newlines \n alone on a disk on Windows.

But THAT'S NOT MANDATORY ! You remain free to do so or not

.

Another thing is that when Python reads files in 'r' mode, the Universal Newline Support (see PEP 278) is enabled by default: it consists in the fact that all types of newlines found by Python in a file are transformed into the single character \n.

But it may also happen that you need to read a file without any transformation of newlines. In this case, instead of disabling the Universal Newline Support, you can read a particular file in mode 'rb'

But you are NOT OBLIGED and I don't incite anybody to do so or the contrary. You do what you want, all that ridiculous stuff is to explain something useful to know.

.

Edit 2

I had tried to use writelines(), but I hadn't thought to use % formating to add a newline with sipmplicity .

Now that I've seen Derek Litz's answer, I have an evident solution:

lot = [('Apples', '=', 10),
       ('Nuts', '<', 20),
       ('Peaches','(Florida)','No stock')]

with open('tototo.txt','w') as f:
    f.writelines( '%s %s %s\n' % tu for tu in lot )

Only if length of the tuples is 3 for all the tuples

eyquem
  • 26,771
  • 7
  • 38
  • 46
  • -1 Please don't incite novice users to write text files in binary mode on Windows. If you're on Windows, you typically *don't* want a lone `\n`, as some Windows software will behave strangely. E.g. Notepad treats a lone `\n` as if it were a zero-width space, not a line separator. Readers which expect cross-border text files can use 'rU' (universal newlines) mode. – John Machin Dec 03 '11 at 09:18
  • @John Machin Where do you see that I incite somebody to write in ``'rb'`` mode on Windows ?! I give an explanation that is hard to find somewhere. People choose and do what they want, after that. Surely, the cases in which it is needed to write in ``'rb'`` on Windows are unfrequent, but it was my case one time and I was in a mess during a long time before understanding alone the reason of weird results I had in special treatment of files on Windows. I didn't want to use ``'rb'`` but I was obliged. – eyquem Dec 03 '11 at 09:40
  • It should be wb not rb for writing binary and you are better off just referring someone to the docs unless you are going to provide a better explanation or some examples: http://docs.python.org/tutorial/inputoutput.html#reading-and-writing-files. It's not "hard to find" if you help them find it. I agree that stating you're inciting novice users to write text files in binary mode is overly harsh, but agree with the down vote nevertheless. – Derek Litz Dec 03 '11 at 13:17
  • 1
    @Eyquem: If you ever needed to write a sole `\n` on Windows, it was because the file was a binary file or it was needed to be written in Unix format. Read PEP 278 a little further than the first line: yes, universal newlines support is enabled by default, but that means "made available unless you exclude it when compiling the C source of Python" -- it is used automatically only by `import` and `execfile`. 'U' or 'rU' is NOT the default mode for reading files. – John Machin Dec 03 '11 at 20:11
1

No one mentioned simply doing:

with open('file_name', 'w') as f:
    for tuple in tuples:
        f.write('%s %s %s\n' % tuple)

This has several ups. It's easier to comprehend what you're doing, the format is painfully obvious and easy to modify, and you never forget to use str(object).

The downside to this compared to the join solutions is if the tuple changes sizes it won't work with one of the following tracebacks:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string

(Try reproducing them as an exercise.)

In my opinion if the tuples are not going to be of varying size the most pythonic thing to do is the version presented here.

import this #and decide for yourself :)

Also, see resources for more info (in order of relevance to the problem):

http://docs.python.org/library/stdtypes.html#string-formatting-operations

http://docs.python.org/library/string.html

http://www.python.org/dev/peps/pep-0292/

Derek Litz
  • 10,529
  • 7
  • 43
  • 53
0

This example will allow you to loop through a list of tuples and write each tuple to a new line in a text file. Note that im using unicode instead of string:

with open('filename.txt','w') as f:
        for tup in list_of_tuples:
            f.write( u" ".join(map(unicode,tup))+u"\n")

The above answers map your data to string format first, which is okay if your data is not already in unicode format.

jxn
  • 7,685
  • 28
  • 90
  • 172