0

My goal is to take lists that contain strings such as ['1 0', '2 0', '3 1 2'] or [['1 0'], ['2 0'], ['3 1 2']]

and turn that into an adjacency list like so: [[1, 0], [2,0], [3,1], [3,2]]

The issue I have is that the last string in the list has more than two digits ['3 1 2']. This causes unpacking the sublist to generate the error shown below:

Traceback (most recent call last):
      File "/tmp/source.py", line 79, in <module>
        for dest, src in nlist:
    ValueError: too many values to unpack (expected 2)

Code so far:

linelist: ['1 0', '2 0', '3 1 2']

newlist = []    
print("linelist1", linelist)
for word in linelist:
    word = word.split(",")
    newlist.append(word)

newlist: [['1 0'], ['2 0'], ['3 1 2']]

adj_list  = {}
nlist = []
for inner_list in newlist:
    values = [int(x) for x in inner_list[0].split()] # splits each sublist
    nlist.append(values)

    adj_list [values[1]] = values[0:]

adj_list = defaultdict(list)

for dest, src in nlist:
    adj_list[src].append(dest)

Should output: [[1, 0], [2,0], [3,1], [3,2]]

dingoyum
  • 25
  • 4
  • Can there be an arbitrary number of ints in a string or is 3 the max? If the former, what should `1 2 3 4 5` yield? – jarmod Nov 10 '22 at 23:29
  • I have absolutely no idea what the code is actually supposed to do. By "adjacent list", did you mean *adjacency list*? If so, why is `adj_list` in the code a dict instead? Please try to be more clear about the presentation - which code that you are showing us, is for which task? When you say "this outputs:", **what is "this"**? If there is an error message, then where is the output coming from? Please also read https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ and think carefully about the intended logic of the program, step by step, in order to ask a **specific** question. – Karl Knechtel Nov 10 '22 at 23:31
  • Arbitrary. I assume you mean those ints would be in a sublist like [1,2,3,4,5] then the output would be: [1, 2], [1, 3], [1,4], [1,5]. – dingoyum Nov 10 '22 at 23:33
  • Hold on. It seems like the code you are showing is entirely about showing what you want to do with `nlist`, after it has been processed? Nothing to do with the actual thing you want to implement? Then it is not helping to explain the problem. What does help is to think about clear, explicit steps to solve the problem, and then work out where you are stuck and ask a more *specific* question. For example, if you have a *single* string like `'3 1 2'`, can you write the code that gives a result `[[3, 1], [3, 2]]`? Can you at least write the code to get the individual numbers, `[3, 1, 2]`? – Karl Knechtel Nov 10 '22 at 23:45
  • Updated the explanation so hopefully, that helps. – dingoyum Nov 10 '22 at 23:47

4 Answers4

1

You can try:

lst = ["1 0", "2 0", "3 1 2"]

out = []
for s in lst:
    n, *rest = map(int, s.split())
    out.extend([n, v] for v in rest)

print(out)

Prints:

[[1, 0], [2, 0], [3, 1], [3, 2]]
Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
0

Essentially all we need to do to get from your desired input to output is

  1. read each entry in the list
  2. split each entry on a space
  3. convert each entry to int
  4. create pairings with first element and all other elements in each sublist. From input ('inp')
['1 0', '2 0', '3 1 2']

in the following function...

def convert_to_pairs(inp: list[str]) -> list[list[int]]:
    xs = [x.split(' ') for x in inp] # split on space
    xs = [[int(y) for y in x] for x in xs] # convert to int
    result = [] # (to store final result)
    for entry in xs:
        if len(entry) <= 2: # we don't need to do any extra stuff
            result.append(entry)
            continue

        for i in range(1, len(entry)):
            result.append([entry[0], entry[i]]) # create each pairing needed

    return result

The output would be

[[1, 0], [2, 0], [3, 1], [3, 2]]
Adam Ali
  • 16
  • 2
  • 1
    Please add some words to describe how this solves the OP's problem – Code-Apprentice Nov 10 '22 at 23:40
  • Welcome to Stack Overflow. Please do not use the snippets feature for languages other than Javascript; it's intended for demonstrating code in the browser, but that doesn't work for other languages. – Karl Knechtel Nov 10 '22 at 23:42
  • @MadisonCourto yes, I understand that the question is a Python question. I edited the answer to avoid using a formatting feature that is inappropriate for Python questions. – Karl Knechtel Nov 10 '22 at 23:50
0

Is this what you want? Reading between the lines here:

def convertList(argi):
    # convert list of strings to list of lists
    resultArr = []
    for item in argi:
        resultArr.append(item.split(" "))
        if len(resultArr[-1]) > 2:
            firstItem = resultArr[-1][0]
            resultArr[-1] = resultArr[-1][1:]
            for item in resultArr[-1]:
                resultArr.append([firstItem, item])
    resultArr = [item for item in resultArr if len(item) == 2]

    return resultArr


print(convertList(['1 0', '2 0', '3 1 2 4 5 6', '3 7 8 9 10 11']))

Output:

[['1', '0'], ['2', '0'], ['3', '1'], ['3', '2'], ['3', '4'], ['3', '5'], ['3', '6'], ['3', '7'], ['3', '8'], ['3', '9'], ['3', '10'], ['3', '11']]
Madison Courto
  • 1,231
  • 13
  • 25
0

Assuming that there are not less than 2 elements in each string.

lst = ['1 0', '2 0', '3 1 2']

nlist = [z.split() for z in lst]

res = []
for i in range(len(nlist)):
    if len(nlist[i]) > 2:
        for k in range(1, len(nlist[i])):
            res.append([nlist[i][0], nlist[i][k]])
    else:
        res.append(nlist[i])

print(res)

and the output is

[['1', '0'], ['2', '0'], ['3', '1'], ['3', '2']]
Yuri Ginsburg
  • 2,302
  • 2
  • 13
  • 16