user9092346
user9092346

Reputation:

How can I multiply elements in one list while providing a range in another

I have two lists that I will later use do determine on how many pages of a document I'm looking at. The first list (l_name) contains the name of the document. The second list (l_depth) contains the number of pages I will look at, always starting from the first one.

The original lists look like this:

l_name = ['Doc_1', 'Doc_2', 'Doc_3']
l_depth = [1, 3, 2]

As I want to use a for loop to indicate each page I will be looking at

for d,p in zip(l_doc, l_page):
  open doc(d) on page(p)
  do stuff

I need the new lists to look like this:

l_doc = ['Doc_1', 'Doc_2', 'Doc_2', 'Doc_2', 'Doc_3', 'Doc_3']
l_page = [1, 1, 2, 3, 1, 2]

How can I multiply the names (l_name --> l_doc) based on the required depth and provide the range (l_depth --> l_page) also based on the depth?

Upvotes: 4

Views: 470

Answers (9)

LiuXiMin
LiuXiMin

Reputation: 1265

Try this:


ret = sum([[ (name, i) for i in  range(1, depth + 1)] for name, depth in zip(l_name, l_depth)], [])
l_doc, l_page = zip(*ret)

Upvotes: 0

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

With builtin zip and itertools.chain.from_iterable functions:

from itertools import chain

l_name = ['Doc_1', 'Doc_2', 'Doc_3']
l_depth = [1, 3, 2]

result = list(chain.from_iterable([n]*d for n, d in zip(l_name, l_depth)))
print(result)

The output:

['Doc_1', 'Doc_2', 'Doc_2', 'Doc_2', 'Doc_3', 'Doc_3']

Upvotes: 2

yatu
yatu

Reputation: 88236

Here's an itertools based one using repeat:

from itertools import repeat

l_name = ['Doc_1', 'Doc_2', 'Doc_3']
l_depth = iter([1, 3, 2])

[i for i in l_name for j in repeat(i, next(l_depth))]
# ['Doc_1', 'Doc_2', 'Doc_2', 'Doc_2', 'Doc_3', 'Doc_3']

Upvotes: 1

Schiz
Schiz

Reputation: 46

l_name = ['Doc_1', 'Doc_2', 'Doc_3']
l_depth = [1, 3, 2]

l_doc = []
l_page = []

for i, j in zip(l_name, l_depth):
    l_doc += [i] * j
    l_page += range(1, j + 1)

print(l_doc)
print(l_page)

Upvotes: 0

olivecoder
olivecoder

Reputation: 2914

Inspired by @zipa answer:

l_doc_page =  [(k,p+1) for i, j in zip(l_name, l_depth) for p,k in enumerate([i]*j)]

That would give you:

[('Doc_1', 1), ('Doc_2', 1), ('Doc_2', 2), ('Doc_2', 3), ('Doc_3', 1), ('Doc_3', 2)]

You can use l_doc_page directly if you were planning to zip the lists together when iterating:

for doc, page in l_doc_page: do_sth(doc, page)

or you can unzip and unpack the lists:

l_doc, l_page = zip(*l_doc_page)

and then you get the result required by the question:

>>> l_doc, l_page=zip(*((k,p+1) for i, j in zip(l_name, l_depth) for p,k in enumerate([i]*j)))
>>> l_doc
('Doc_1', 'Doc_2', 'Doc_2', 'Doc_2', 'Doc_3', 'Doc_3')
>>> l_page
(1, 1, 2, 3, 1, 2)

Upvotes: 0

Wimanicesir
Wimanicesir

Reputation: 5121

We have all good answers already, but hey I was doing it already so here you go:

l_name = ['Doc_1', 'Doc_2', 'Doc_3']
l_depth = [1, 3, 2]
l_result = []
index = 0

for depth in l_depth:
  for times in range(depth):
    l_result.append(l_name[index])
  index +=1

print(l_result)

Upvotes: 0

Florian H
Florian H

Reputation: 3082

For the page list you can do the same as zippa suggested:

[k+1 for i, j in zip(l_name, l_depth) for k in range(j)]

output:

[1, 1, 2, 3, 1, 2]

Upvotes: 1

Arkistarvh Kltzuonstev
Arkistarvh Kltzuonstev

Reputation: 6920

Try this :

l_name = ['Doc_1', 'Doc_2', 'Doc_3']
l_depth = [1, 3, 2]
l_doc = []
for i,j in zip(l_name, l_depth):
    l_doc += [i]*j
# ['Doc_1', 'Doc_2', 'Doc_2', 'Doc_2', 'Doc_3', 'Doc_3']

l_page = [k for _,j in zip(l_name, l_depth) for k in range(1,j+1)]
# [1, 1, 2, 3, 1, 2]

Upvotes: 2

zipa
zipa

Reputation: 27869

You can get your list with comprehension:

[k for i, j in zip(l_name, l_depth) for k in [i]*j]

Upvotes: 3

Related Questions