How to get ['1 0', '2 0', '3 1 2'] to be [[1, 0], [2,0] , [3,1] , [ 3,2] ] in so I can unpack the values. Python. Adjacency list

Question:

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]]

Asked By: dingoyum

||

Answers:

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]]
Answered By: Andrej Kesely

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]]
Answered By: Adam Ali

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']]
Answered By: Madison Courto

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']]
Answered By: Yuri Ginsburg