1

This may be a duplicate question, but I want to find out is there a way to unpack a list of lists and make a variable from an unpacked result? I have a data in the file like:

'[416213688, 422393399, 190690902, 81688],| [94925847, 61605626, 346027022],| [1035022, 1036527, 1038016]'

So I open a file and make it a list

with open ('data.txt', "r") as f:
   a = f.read()
a = a.split("|")
print(*a)

Output:

[416213688, 422393399, 190690902, 81688], [94925847, 61605626, 346027022], [1035022, 1036527, 1038016]

This is the output I need for next step of my program. But I can't make this result a variable for using it further. It gives me a SyntaxError: can't use starred expression here if I try:

a = (*a) 

I tried making it by using zip, but it gives me incorrect output, similar to what is described in the question zip function giving incorrect output.

<zip object at 0x0000000001C86108>

So is there any way to unpack a list of list and get an output like:

[1st list of variables], [2nd  list of variables], [etc...]

if i use itertools i get:

   l = list(chain(*a))
   Out: ['[', '4', '1', '6', '2', '1', '3', '6'...

that is not required

So the working option is https://stackoverflow.com/a/46146432/8589220:

 row_strings = a.split(",| ")
 grid = [[int(s) for s in row[1:-1].split(", ")] for row in row_strings]
 print(",".join(map(str, grid)))
miken32
  • 42,008
  • 16
  • 111
  • 154
NagaevAF
  • 21
  • 1
  • 4
  • You can try list comprehensions like [x for l in list for x in l]. – Fady Saad Sep 10 '17 at 23:14
  • Zip doesn't give 'incorrect output', you might be using it incorrectly. It's also not clear exactly what you're trying to accomplish - your data is in a variable and that variable contains a list of lists. – pvg Sep 10 '17 at 23:16
  • 2
    You can use [`itertools.chain`](https://docs.python.org/3/library/itertools.html#itertools.chain): `from itertools import chain; l = list(chain(*a))`. – Christian Dean Sep 10 '17 at 23:18
  • Are you looking for [`json.loads`](https://docs.python.org/3/library/json.html#json.loads)? – Ry- Sep 10 '17 at 23:19
  • What are you trying to do? `split()` returns a list. So calling `a = list(a)` is redundant. Does this unpacked variable need to be an iterable or a single line of strings/ints/chars? – pstatix Sep 10 '17 at 23:23
  • I don't understand what you expect `a = (*a)` to do; and as noted, `a = list(a)` is redundant at that point in the program. It *vaguely looks like* what you're *really trying to do* is take a string like `"[1, 2, 3]"` and convert it into the list `[1, 2, 3]`. Is that it? – Karl Knechtel Sep 10 '17 at 23:31

2 Answers2

1

Here's a quick and dirty way to parse the string into a two-dimensional grid (i.e.: a list, which itself contains a list of integers):

row_strings = a.split(",| ")
grid = [[int(s) for s in row[1:-1].split(", ")] for row in row_strings]
print("\n".join(map(str, grid)))
# Out:
# [416213688, 422393399, 190690902, 81688]
# [94925847, 61605626, 346027022]
# [1035022, 1036527, 1038016]
Adriano
  • 1,697
  • 24
  • 27
0

Let's start with the raw output (I'm just manually going to make the string, but this is equivalent to your read method)

a = '[416213688, 422393399, 190690902, 81688],| [94925847, 61605626, 346027022],| [1035022, 1036527, 1038016]'

This is now just one long string. Let's make it a list of strings

a = a.split(',|')

I did ',|' instead of just '|' because you'll want to get rid of the comma too.

Now a looks like this:

>>> ['[416213688, 422393399, 190690902, 81688]', ' [94925847, 61605626, 346027022]', ' [1035022, 1036527, 1038016]']

It's a list of strings that look like arrays. Let's turn those strings into arrays of integers. One way we can do that is with ast.literal_eval(). What it does is takes a string as the argument and attempts to interpret whatever is in that string as a Python literal. It doesn't like leading whitespace, so we remove that first with .strip().

import ast
a = [ast.literal_eval(arr.strip()) for arr in a]

What this does is it takes each string in a, literal_eval's it, and puts those into a list.

This should return the code you want.

[[416213688, 422393399, 190690902, 81688], [94925847, 61605626, 346027022], [1035022, 1036527, 1038016]]
Nick T
  • 25,754
  • 12
  • 83
  • 121