Asked  7 Months ago    Answers:  5   Viewed   27 times

Is there a built-in function that works like zip() but that will pad the results so that the length of the resultant list is the length of the longest input rather than the shortest input?

>>> a = ['a1']
>>> b = ['b1', 'b2', 'b3']
>>> c = ['c1', 'c2']

>>> zip(a, b, c)
[('a1', 'b1', 'c1')]

>>> What command goes here?
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]

 Answers

49

In Python 3 you can use itertools.zip_longest

>>> list(itertools.zip_longest(a, b, c))
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]

You can pad with a different value than None by using the fillvalue parameter:

>>> list(itertools.zip_longest(a, b, c, fillvalue='foo'))
[('a1', 'b1', 'c1'), ('foo', 'b2', 'c2'), ('foo', 'b3', 'foo')]

With Python 2 you can either use itertools.izip_longest (Python 2.6+), or you can use map with None. It is a little known feature of map (but map changed in Python 3.x, so this only works in Python 2.x).

>>> map(None, a, b, c)
[('a1', 'b1', 'c1'), (None, 'b2', 'c2'), (None, 'b3', None)]
Tuesday, June 1, 2021
 
JackTheKnife
answered 7 Months ago
66

If you are zipping more than 2 lists (or even only 2, for that matter), a readable way would be:

[list(a) for a in zip([1,2,3], [4,5,6], [7,8,9])]

This uses list comprehensions and converts each element in the list (tuples) into lists.

Monday, June 21, 2021
 
JohnnyW
answered 6 Months ago
63

Here's an implementation:

// Takes the list as a parameter, can use pimp-my-library if you want
def groupWith[A](xs: List[A], f: (A, A) => Boolean) = {
  // helper function to add "e" to any list with a member that matches the predicate
  // otherwise add it to a list of its own
  def addtoGroup(gs: List[List[A]], e: A): List[List[A]] = {
    val (before, after) = gs.span(_.exists(!f(_, e)))
    if (after.isEmpty)
      List(e) :: gs
    else
      before ::: (e :: after.head) :: after.tail
  }
  // now a simple foldLeft adding each element to the appropriate list
  xs.foldLeft(Nil: List[List[A]])(addtoGroup)
} 

groupWith(list, { (e: Item, c: Item) =>
                    (e.num - 1 == c.num || e.num + 1 == c.num) && e.color == c.color})

//| res0: List[List[groups.groups.Item]] =
//         List(List(Item(16,red)),
//              List(Item(15 ,blue)), 
//              List(Item(14,red), Item(13,red)))
Saturday, August 7, 2021
 
mariaoialvarez
answered 4 Months ago
57

You could try listening for the window.beforeunload event.

The beforeunload event is fired when the window, the document and its resources are about to be unloaded. The document is still visible and the event is still cancelable at this point.

useEffect(() => {
  const unloadCallback = (event) => { ... };

  window.addEventListener("beforeunload", unloadCallback);
  return () => window.removeEventListener("beforeunload", unloadCallback);
}, []);

Note: This will respond to anything that causes the page to unload though.

Note 2:

However note that not all browsers support this method, and some instead require the event handler to implement one of two legacy methods:

  • assigning a string to the event's returnValue property
  • returning a string from the event handler.
Saturday, August 7, 2021
 
Akarun
answered 4 Months ago
13

Try the *:

In [2]: lis=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [3]: zip(*lis)
Out[3]: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
Saturday, August 14, 2021
 
Aniket Thakur
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share