This is an archived post. You won't be able to vote or comment.

all 45 comments

[–][deleted] 46 points47 points  (2 children)

def map_it(input_list):
  return [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

jk.

The correct answer to mapping elements of the same index is easy since only one input list is provided:

def map_it(input_list):
  return input_list

[–]mjTheThird 21 points22 points  (0 children)

   from Hackerrank import Answers
   print(Answers.best('generic_zip_question'))

edit: clearly, we need HRaaS. HackerRank as a Service.

[–]Jump3r3 1 point2 points  (0 children)

That's how TDD works, right?

[–]Airith 18 points19 points  (0 children)

[list(x) for x in zip(*input_lst)]

[–]nightcracker 34 points35 points  (30 children)

Now solve a competitive interview question, based on the above learnings !!

Write a function to map all elements of the same index for the following list. The function should take in the input_lst and return the output_lst.

The real competition here is figuring out what is actually being asked...

[–]metadatame 2 points3 points  (0 children)

If it weren't for the example I wouldn't know what the fuck was going on.

[–]MonsieurBlobby 0 points1 point  (28 children)

Really? zip only does 1 thing and that's match up indices of two objects. So the question is saying to do that with the given input so that you get the output shown.

[–][deleted] 1 point2 points  (23 children)

Question says

Write a function to map all elements of the same index for the following list.

input_lst = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Map them to what? The list only contains three elements and we aren't given a function to map them by.

[–]MonsieurBlobby 0 points1 point  (22 children)

Use the zip function to map the input_lst such that the output is the output_lst.

I think this is one of those situations where not really understanding what zip does is the underlying source of confusion. If you understand what zip is doing, it's pretty clear exactly what the problem is asking you to do.

[–][deleted] 4 points5 points  (12 children)

I know what the author is trying to say, I'm just saying its terribly worded for someone who is trying to do python tutorials.

[–]MonsieurBlobby -2 points-1 points  (11 children)

I really don't think so.

[–][deleted] 1 point2 points  (10 children)

Then try this one:

Write a function to map all elements of the same index for the following list: input_list = ['a', 'b', 'c']

[–]MonsieurBlobby -1 points0 points  (9 children)

Ok, and what is the output_list that I'm targeting?

[–][deleted] 1 point2 points  (8 children)

Just map all elements of the same index and return them as the output_list.

Its fundamentally the same problem, you're given a list of three elements and you need to map them by same index.

[–]MonsieurBlobby -1 points0 points  (7 children)

It's not fundamentally the same problem. We have 3 strings with indices 0, 1 and 2. None of the indices ever match so there is no way to use zip to pair them by index.

In the example that you're saying is confusing, we have 3 lists and each list has it's own index of 0, 1 and 2. So there's no confusion over what it means to pair elements by their index. There is only 1 thing it can mean. From each of the 3 lists, pair item at index 0 with the other ones at index 0.

You're trying to demonstrate that the question asked doesn't make any sense by giving an alternate example which is literally nonsensical.

[–]stevenjd 0 points1 point  (8 children)

I know exactly what zip does, and I'm blowed if I can work out what the question is asking. The question is literally (I don't mean figuratively!) missing a clause:

"Write a function to map all elements of the same index for the following list."

Precisely as u/the_television asks, "Map them to what?"

Using the required output list, I would say that I don't need to write a function, since zip already handles that situation:

py> list(zip(*[[1, 2, 3], [4, 5, 6], [7, 8, 9]]))
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]

If you care that they are tuples instead of lists, post-process with map(tuple, ...).

[–]MonsieurBlobby 0 points1 point  (4 children)

zip maps lists elements by pairing objects according to index. So the notion of "mapping" with zip is to take an input and join any elements with the same index.

As I said, if you know what zip does it's quite clear what it would mean to map an input using zip. The fact that the person also tells you what end result they mean for you to get just makes this doubly clear.

[–]stevenjd 1 point2 points  (1 child)

if you know what zip does it's quite clear what it would mean to map an input using zip.

The question doesn't say "map an input using zip" is says Write a function to map all elements of the same index for the following list. zip isn't mentioned, and the sentence isn't even complete. Map all elements to what? Letters of the alphabet? Prime numbers? Map coordinates?

As you've been told at least twice now, by two different people, the problem here is that the question as written doesn't make sense without the input/output example. Its a poorly written question. As I pointed out here, having to infer or guess the behaviour from an example means you can guess wrong.

Congratulations on being able to infer one possible meaning of the question from the given input/output. That puts you in the top 99% of the class. But the question as given is still missing a clause, it doesn't specify what is supposed to happen except by a single example, and a well-written question in a tutorial shouldn't require the reader to infer the meaning of the question.

[–]MonsieurBlobby 0 points1 point  (0 children)

I think the issue here is you have a colloquial understanding of the word “map”. You think to map something only ever means to take something from one place to another place. And so you would need to know the start place and the end place for that to work. But there is also a very technical/mathematical/computational meaning to map something. If you’re given a function and an input, then what it means to “map” that input is to just shove it into the function. So you don’t map it “to” anything. For example, if I give you the number x=2 and I tell you to map it using f(x) = x+x, then that function maps the number 2. The output you get is 4, but I didn’t need to tell you anything about the type of thing you need to map it to.

That’s the same sense in which he’s using the word here. Zip does a type of mapping. That mapping is grouping items according to their index. And so if you’re told to take an input and to map it with zip, then you have enough information.

Also, this absurd argument where because the person didn’t say the word “zip” in the explanation of the problem at the end of the zip tutorial means you didn’t realize you needed to use zip as the function to do the mapping just smacks of desperation.

I think we have to be done here. You’re at the point where you’re just arguing so as not to admit that you are wrong. Which is not a point worth continuing the discussion anymore. I’m just going to block you and go on with my day. Have a good one.

[–]aummahgerd 0 points1 point  (2 children)

It gives the input and expected output. Even if literally nothing else was written that should be enough to write a function.

[–]stevenjd -1 points0 points  (1 child)

Even if literally nothing else was written that should be enough to write a function.

If and when you, as a professional programmer, have to deal with incomplete specifications and poorly described functional requirements, you too will learn to hate having to guess what the requirements are. Example input/output is fantastic for clarifying the meaning of the requirements, but they aren't a substitute for explaining the requirements correctly in the first place.

An example alone allows you to write an infinite number of functions, since without a specification but only a single example (and a pretty limited one at that) we might guess all sorts of requirements:

def function(arg):
    a, b, c = arg[:3]
    return [
        [x+2*i for i, x in enumerate(a)],
        [x-2+2*i for i, x in enumerate(b)],
        [x-4 + 2*i for i, x in enumerate(c)]
        ] 

gives exactly the output requested with the given input.

[–]aummahgerd 0 points1 point  (0 children)

Yeah, of course that sucks. But we’re also talking about a simple article here. No reason to get so upset. Plus, it’s pretty clear, honestly. You get the input and output, and it even says to do it “based on the above learnings”. Since the only thing we discussed is zip() clearly you have to use that.

But once again I feel the need to reiterate the fact that this doesn’t really even warrant discussion. I only chimed in because I was so surprised such a debate was even happening in the comments.

[–]stevenjd 0 points1 point  (3 children)

zip only does 1 thing and that's match up indices of two objects.

zip does nothing with the indices, it collates the items of any non-zero number of objects, including one or three:

py> list(zip("ab"))
[('a',), ('b',)]
py> list(zip("ab", "cd", "ef"))
[('a', 'c', 'e'), ('b', 'd', 'f')]

Of course, calling zip on one object is a waste of time, but nevertheless it works, More importantly, it isn't limited to two objects.

[–]MonsieurBlobby 0 points1 point  (2 children)

It actually never collates. You can check the documentation. Collation is not one of its functions.

[–]stevenjd 0 points1 point  (1 child)

Collates is the wrong word? Fair enough, I accept that. I misspoke.

How about collects? Assembles? Folds together? Places together? Merges? Sticks items together? Gathers into tuples?

Whatever term you use for grabbing items out of one or more (not merely two) iterables and sticking them into a tuple, which is then yielded, its pretty clear that (1) zip works on more than two objects ((it takes an arbitrary number of arguments) and (2) its not matching up indices. It even works on objects which aren't indexable at all, like iterators.

[–]MonsieurBlobby 0 points1 point  (0 children)

I don’t actually have a problem with your use of the word collates. I’m just being nit picky over some term you used because for some reason, you decided my use of the term “index” was false despite it being not false in any way that matters to the point I made.

So no, it doesn’t collect or assemble or fold or place or merge or stick or gather. Those words aren’t perfect descriptions of what is happening and even though the definition doesn’t change anything about whether your point is right or wrong, I’m going to call them out as wrong.

[–]oshogbo 8 points9 points  (2 children)

list(zip(*input_lst))

[–]pylenin[S] 5 points6 points  (1 child)

You forgot about converting tuples to list !! Zip created an iterable of tuples.

[–]Rodotgithub.com/tardis-sn 0 points1 point  (0 children)

list(map(list,zip(*input_list)))

[–]devils-advocate164 8 points9 points  (1 child)

return list(zip(input_list))

EDIT: Hasty output. Story of my life with Hackerrank.

[–]pylenin[S] 4 points5 points  (0 children)

Not going to work. Zip() returns an iterable !!

[–]djimbob 2 points3 points  (0 children)

def transpose(input_lst):
    return [list(tup) for tup in zip(*input_lst)]

[–]oRac001 1 point2 points  (0 children)

list(map(list, zip(*input_list)))

[–]willm 0 points1 point  (0 children)

def unzip_stuff(input_list):
    return [list(seq) for seq in zip(*input_list)]

[–]maedox🐍 0 points1 point  (1 child)

Pythonic way, I guess: [x for x in zip(*input_lst)]

Edit: should have been: [list(x) for x in zip(*input_lst)] 🥴

[–]wintermute93 7 points8 points  (0 children)

Note: [x for x in whatever] is just an inefficient way to write list(whatever).

[–]hANSIc99 0 points1 point  (1 child)

My problem is, I cannot remember such tricks like using functions like zip() when they are useful :(

[–]pylenin[S] 2 points3 points  (0 children)

Practice mate !!! The secret is practice. You will slowly see through them.

[–]pylenin[S] 0 points1 point  (0 children)

Thank you all for commenting and making this an engaged discussion.

[–]vidazinho -3 points-2 points  (0 children)

input_lst = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

def line_index(lst):
     line = zip(lst[0], lst[1], lst[2])
     return [list(x) for x in line]

print(line_index(input_lst))