On Mon, Mar 29, 2021 at 1:56 AM Greg Wooledge <g...@wooledge.org> wrote:
> Python is different: > > >>> y = ["a", "b", "c", "d"] > >>> dict(zip(y[::2], y[1::2])) > {'a': 'b', 'c': 'd'} > >>> x = ["a", "b", "c"] > >>> dict(zip(x[::2], x[1::2])) > {'a': 'b'} > > It seems to discard the last (unmatched) value. Also, dear gods, what > is that horrible syntax they forced me to google for... and it took MANY > tries to find it, too. > That's a bit different, since it's not really a built-in feature but doing it manually, just using some rather terse syntax and tersely named functions. Apart from Python having such stuff available, it's not really unlike just filling an associative array from an indexed one with a loop in the shell. And if you do it manually, you can do anything you like. You can't do it directly in Python the same way as in Zsh, Bash or Perl, though. [ more Python follows, ignore if you like ] Just dropping a list to dict() would probably be the most direct equivalent, but it doesn't work: >>> dict([ "a", "b", "c", "d" ]) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: dictionary update sequence element #0 has length 1; 2 is required You have to pair the elements up (which is what zip() does there): >>> dict([ ("a", "b"), ("c", "d") ]) {'a': 'b', 'c': 'd'} And you can't leave unpaired elements (or sets of three): >>> dict([ ("a", "b"), ("c",) ]) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: dictionary update sequence element #1 has length 1; 2 is required Using 'itertools.zip_longest' like Andreas showed would be another alternative for doing it manually. It would generate explicit 'None's to fill the shorter list, which then would appear in the result. Of course, that's possible because Python has 'None' to begin with, like Perl has 'undef'. The shell doesn't really have the equivalent of that. IMO, an unset value would be the nearest equivalent (vs. an empty string being an explicitly defined value), but I guess that's arguable. I'm not sure what you meant as the horrible syntax, and you probably don't want to know this, :) but the index in x[1::2] takes every other element of 'x', starting at 1. Somewhat similarly to a brace expansion like {1..9..2}. The zip() there pairs the even and odd halves together.