0

Given a list of lists where the number of lists, and the number of elements within is variable. For example:

import random import string bar = lambda: [random.choice(string.ascii_letters) for _ in range(random.randint(1,5))] branches = [bar() for _ in range(4)] >>> branches [['t'], ['S', 't'], ['Q'], ['M', 'a', 'J', 'x', 'Y']] 

I'm wondering if there is a more succinct way to create a list of tuples which index the list. Something more concise than this:

nodes = [] for branch in range(len(branches)): for node in range(len(branches[branch])): nodes.append((branch, node)) >>> nodes [(0, 0), (1, 0), (1, 1), (2, 0), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4)] 

Couldn't this be done with a list comprehension? I'm just having some trouble nailing it and am confident there's a brainiac out there with a big hammer.

The ultimate goal is to randomly visit each node once, and only once, and during the visit, to know exactly where the current node lies in the grand scheme of things. So I shuffle the result random.shuffle(nodes) and loop over it—using the tuple to access the original list via branches[node[0]][node[1]]. Better ideas are welcome.

1
  • 2
    The nested for loop can be written as a list comprehension: [(branch, node) for branch in range(len(branches)) for node in range(len(branches[branch]))]. Commented Jun 17, 2015 at 0:23

3 Answers 3

2

Enumeration really isn't needed:

In [1]: branches = [['t'], ['S', 't'], ['Q'], ['M', 'a', 'J', 'x', 'Y']] [(i, j) for i in range(len(branches)) for j in range(len(branches[i]))] Out[1]: [(0, 0), (1, 0), (1, 1), (2, 0), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4)] 

or at least not for both:

In [2]: branches = [['t'], ['S', 't'], ['Q'], ['M', 'a', 'J', 'x', 'Y']] [(i, j) for i,branch in enumerate(branches) for j in range(len(branch))] Out[2]: [(0, 0), (1, 0), (1, 1), (2, 0), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4)] 
Sign up to request clarification or add additional context in comments.

Comments

1

The enumerate function allows you to easily access each element's index and value.

>>> branches = [['t'], ['S', 't'], ['Q'], ['M', 'a', 'J', 'x', 'Y']] >>> [(idx, id) for idx,val in enumerate(branches) for id,v in enumerate(val)] [(0, 0), (1, 0), (1, 1), (2, 0), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4)] 

Comments

0

If the goal is to iterate over every item randomly:

import random l = [['t'], ['S', 't'], ['Q'], ['M', 'a', 'J', 'x', 'Y']] l2 = [x for y in l for x in y] random.shuffle(l2) 

1 Comment

iterate over them randomly, but with the indicies of the current node

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.