11

I have a list, in which is another list and I want to doc.write(a)

a = [[1, 2, "hello"],
     [3, 5, "hi There"],
     [5,7,"I don't know"]]
doc.write(''.join(a))



TypeError: sequence item 0: expected str instance, list found

How can I handle this, do I have to make a for-loop in which I join and add all the sublists?

The real goal was to make it somehow readable for human beeing, but I didn't wanted a finished solution from you.

inetphantom
  • 2,498
  • 4
  • 38
  • 61
  • What do you want to do with the numbers? – Ignacio Vazquez-Abrams Oct 31 '13 at 22:39
  • 3
    Please show the actual output you want. – abarnert Oct 31 '13 at 22:39
  • I want to write the list in a textfile. Somehow. – inetphantom Oct 31 '13 at 22:51
  • @inetphantom: And you don't care how at all? It doesn't need to be re-parseable by your code, or readable by a human being, or importable into some other program, or anything? In that case, just do `write('stuff')` and you're done. – abarnert Oct 31 '13 at 23:09
  • @abarnert What is 'stuff' ?? – eyquem Oct 31 '13 at 23:26
  • @eyquem: It's a perfectly valid string that can be used to represent any object, when you have absolutely no requirements on the object's representation. – abarnert Oct 31 '13 at 23:29
  • @inetphantom What is your aim when writing an object as a string in a text file ? Is it only to make it readable ? Or will youhave to get it back and to use it as a Python ? According to what the answer is, the solution to your question will be different. – eyquem Oct 31 '13 at 23:56

7 Answers7

13

You can try something like

>>> a = [[1, 2, "hello"],[3, 5, "hi There"],[5,7,"I don't know"]]
>>> 
>>> ''.join(str(r) for v in a for r in v)
"12hello35hi There57I don't know"

i.e.

doc.write(''.join(str(r) for v in a for r in v))
arshajii
  • 127,459
  • 24
  • 238
  • 287
  • This has been a long time since that answer - with [`'\t'.join()`](https://docs.python.org/3/library/stdtypes.html#str.join) this can be beautified to a tab separated list which might be more readable. – inetphantom Jan 15 '19 at 13:06
4

There are different legal things you can do, and no way for anyone to say which one is right without knowing which one you want.


First, you can just write the str or repr of a:

>>> a=[[1, 2, "hello"],[3, 5, "hi There"],[5,7,"I don't know"]]
>>> repr(a)
'[[1, 2, \'hello\'], [3, 5, \'hi There\'], [5, 7, "I don\'t know"]]'

Note that this is what print does (it prints the str of whatever you give it—although with a list, the str is identical to the repr; they're both effectively '[' + ', '.join(map(repr, self)) + ']').


Second, you could use a format that's designed for data persistent, like JSON:

>>> json.dumps(a)
'[[1, 2, "hello"], [3, 5, "hi There"], [5, 7, "I don\'t know"]]'

Third, you can join together the repr of each element of a in some way of your choosing, which is trivial with a map or a comprehension. For example:

>>> '[' + ', '.join(map(repr, a)) + ']'
'[[1, 2, \'hello\'], [3, 5, \'hi There\'], [5, 7, "I don\'t know"]]'

… or …

>>> 'My stuff includes: ' + ','.join(map(repr, a)) + '\n'
'My stuff includes: [1, 2, \'hello\'],[3, 5, \'hi There\'],[5, 7, "I don\'t know"]\n'

Or you can do the same thing recursively.

Or you can flatten the list (e.g., flatten it one step with itertools.chain, or recursively with the recipes from the itertools docs or with the more-itertools package) and then stringify the pieces however you want and then join them up.

Or you can just write the word LIST.

All of those are perfectly valid things to pass to write.

abarnert
  • 354,177
  • 51
  • 601
  • 671
3

List comprehension would be the best choice:

>>> ''.join([str(item) for sublist in a for item in sublist])
"12hello35hi There57I don't know"

It's the most recommended approach in a similar SO question, considering performance and syntax.

Community
  • 1
  • 1
jlr
  • 1,362
  • 10
  • 17
1

I was looking for an answer to this as well. After reading the comments here, this is what I came up with:

I was looking for an answer to this as well. After reading the comments here, this is what I came up with:

','.join(str(' '.join(str(x) for x in v)) for v in a)

This creates something like:

1 2 hello,3 5 hi There,5 7 I don't know

If you want all spaces as delimiters, then use ' ' instead of ',' at the front.

Clash
  • 81
  • 7
0

What about using itertools?

from itertools import chain
doc.write(''.join(map(str, chain(a))))

Alternatively:

doc.write(''.join(str(i) for sub_list in a for i in sub_list))

You suggested a using a for loop. You could indeed do this, although the options above are probably better.

new_a = []
for sub_list in a:
    for i in sublist:
        new_a.append(str(i))
doc.write(''.join(new_a))

This is basically the previous option, but unrolled.

Unless you want to just write the first list, in which case you could do this:

doc.write(''.join(map(str, a[0])))
rlms
  • 10,650
  • 8
  • 44
  • 61
0

It's difficult for me to be sure, because your question is too short, but it seems to me that you are in a XY problem, that is to say :
you ask a question about a Y problem that you think of as being the one that needs to be solved to goes out of an uphill X problem. But your real problem is that you think that the Y problem is the way to answer to the real problem X AND that you present here only the Y problem.
Writing that, I only paraphrase what is said here: XY problem

If I am right, my opinion is that you will have a better way to solve your real X problem using one of the following tools, that allow to serialize an object and to record the serialized object in a file:

pickle

marshal

shelve

I won't paraphrase and repeat all is the docs on these tools, read them.

.

If i am wrong and that you really just want to write an object under the form of a string representation, you can also do:

from pprint import pformat

a = [[1, 2, "hello"],
     [3, 5, "hi There"],
     [5,7,"I don't know"]]

with open('doc.txt','w') as f:
    f.write(pformat(a,width=12))
Community
  • 1
  • 1
eyquem
  • 26,771
  • 7
  • 38
  • 46
  • This is more of a comment than an answer. – abarnert Oct 31 '13 at 23:09
  • I don't think this is helpful. The OP isn't asking about how to do something wrongly (e.g. parse XML with regex), but a reasonable question. The modules you have given aren't very helpful in terms of writing to a human-readable "**text**file" (my emphasis), and I believe that link-only answers are discouraged. – rlms Oct 31 '13 at 23:11
  • @abarnert I habitually appreciate your answers and comments, but presently I don't understand this comment of yours. It seems to me that the crucial point is: am I right when thinking that the OP tries to find a way to apply a wrong solution to his problem instead of finding a real good and adapted soulution. If yes my advice, that answers to his X problem instead of answering to the Y pseudo-solution, deserves as much an answer format as the other answers, in my opinion. – eyquem Oct 31 '13 at 23:38
  • @sweeneyrod Where do you see allusions to XML and regex in the question and in my answer ????? – eyquem Oct 31 '13 at 23:44
  • @sweeneyrod _"I don't think this is helpful"_ : you are right at one condition: if the OP wants the data written in the text file to be only human-readable. I personally thought that, as it us usual in this kind of questions, he wants to store the data for a subsequent use. If I am right, my answer is justified; and I don't think it's needed to repeat explanations that the docs will give to the reader of the linked pages if he does. – eyquem Oct 31 '13 at 23:51
  • @eyquem: I agree that this is probably an XY question, or at least an ill-formed question that could do with some consideration of the X behind the Y. But that's something you should say as a comment or a reason for a close vote. An answer is supposed to actually answer the question, in a way that will benefit future people with the same question. If you believe there is no possible way to provide such an answer to the question, there shouldn't be an answer at all, and the question should be closed. – abarnert Nov 01 '13 at 00:26
  • @abarnert I repeat: if I am right on the XY nature of the question, I esteem that my answer will bring more benefit to the OP than the other answers, it doesn't need to be long in this case. If I am right, the OP will upvote my answer and every future (hypothetical) reader will see my more pertinent answer. Not the case if my advice would be in a comment. Before any precision or reaction given by the OP, I, as everybody else, don't know if my opinion is the good one or not. But I claim my right to think that I maybe do the more beneficial advice and to choose to give it as a full answer – eyquem Nov 01 '13 at 01:24
  • @abarnert By the way, when you write _"An answer is supposed to actually answer the question"_ , you imply that nobody should ever signal to an OP that he is struggling in a wrong direction because (s)he is in a XY appréciation of hos/her problem. I don't agree with your postulate. – eyquem Nov 01 '13 at 01:27
  • @eyquem: Please read the FAQ and other help. The way to signal that a question is not a useful question is to vote to close it, and optionally write a comment, not to write an answer. If you don't think the site should work that way, there's plenty of room for debate on how the site should work on meta. – abarnert Nov 01 '13 at 01:37
  • @abarnert Which part of the FAQ please ? – eyquem Nov 01 '13 at 01:46
  • @abarnert By the way, what do you call a "useful question" ? From what you said, you seem to think that it's more important that the answers and comments obtain a "nihil obstat" than being beneficial for the OP. Is useful more important for the site or for the OP ? – eyquem Nov 01 '13 at 01:56
  • @abarnert I read that in the **help** section concerning answers. ``What, specifically, is the question asking for? Make sure your answer provides that – or a viable alternative. The answer can be “don’t do that”, but it should also include “try this instead”. Any answer that gets the asker going in the right direction is helpful, but do try to mention any limitations, assumptions or simplifications in your answer. Brevity is acceptable, but fuller explanations are better`` It appear to me that it precisely justifies my kind of answer – eyquem Nov 01 '13 at 02:03
  • 1
    Explaining why the question is not a good question is not an answer. Any answer that roughly matches one of the standard close reasons is not an answer. Even if it were, a list of links with no commentary is not an answer. So, this is not an answer. (That being said, whoever downvoted your answer should probably have flagged it as "Not an Answer" instead, as explained [here](http://meta.stackexchange.com/questions/118582/what-is-an-acceptable-answer).) – abarnert Nov 01 '13 at 02:12
  • @eyquem The regex-XML thing was an example of something that would definitely be the XY problem (regex is definitely not the right tool to parse XML, so the questioner should be given an answer detailing the right way, not a horribly complex regex). From the question, I presumed that they wanted to get `''.join(a)` for a flatten version of `a`, from the code they originally posted. This answer isn't related to that at all, it addresses a different problem entirely, so I think it would be at least useful to mention what you _think_ the OP's problem is as well, rather than just confusing them. – rlms Nov 01 '13 at 12:00
0

You can also just use a simple list comprehension like this:

doc.write([x for x in i for i in a])
eatsfood
  • 950
  • 2
  • 21
  • 31