1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AtCoder Beginner Contest 128 B - Guidebookをpythonでワンライナーで解く

Last updated at Posted at 2019-05-31

@shiracamus さんからご指摘を頂き修正致しました。

コード

print(*[s[2] for s in sorted([input().split() + [i + 1] for i in range(int(input()))], key=lambda x:(x[0], -int(x[1])))], sep='\n')

解説

見にくいので改行を入れて見やすくします。

print(
    *[s[2] for s in sorted(
        [input().split() + [i + 1] for i in range(
            int(input())
        )],
        key=lambda x:(x[0], -int(x[1]))
    )],
    sep='\n'
)

ネストの深いところから見ていきます。

int(input())

Nを受け取ります。

[input().split() + [i + 1] for i in range(
    int(input())
)]

Nの回数分、入力を受け取り分割します。
そして、レストランの番号が欲しいのでi + 1をリストの末尾に追加します。
番号は1からスタートするので+ 1しています。

sorted(
    [input().split() + [i + 1] for i in range(int(input()))],
    key=lambda x:(x[0], -int(x[1]))
)

以下の通りにソートを行います。

  • 市名が辞書順で早いものから紹介していく。
  • 同じ市に複数レストランがある場合は、点数が高いものから紹介していく。

点数をマイナスにすると、昇順ソートで点数の高い順になります。

print(
    *[s[2] for s in sorted(
        [input().split() + [i + 1] for i in range(int(input()))],
        key=lambda x:(x[0], -int(x[1]))
    )],
    sep='\n'
)

レストラン番号のみのリストを作り、*でunpackingします。
区切り文字を\nにし、出力します。

まとめ

自力でワンライナーにしたけど詰めが甘かった。

修正前のコード

コード

print('\n'.join([l[2] for l in sorted(sorted([[l[0], -int(l[1]), str(l[2] + 1)] for l in (input().split() + [i] for i in range(int(input())))], key=lambda x: x[1]), key=lambda x: x[0])]))

解説

まず、見やすくします。

print(
    '\n'.join(
        [l[2] for l in sorted(
            sorted(
                [[l[0], -int(l[1]), str(l[2] + 1)] for l in (
                    input().split() + [i] for i in range(
                        int(input())
                    )
                )],
                key=lambda x: x[1]
            ),
            key=lambda x: x[0]
        )]
    )
)

ネストが深いところから見ていきます。

int(input())

Nを受け取ります。

input().split() + [i] for i in range(
    int(input())
)

Nの回数分入力を受け取り、分割します。
レストランの番号が欲しいのでiをリストに追加して渡します。

[[l[0], -int(l[1]), str(l[2] + 1)] for l in (
    input().split() + [i] for i in range(int(input()))
)],

受けった値を整形します。

# ↓これ
['khabarovsk', '20', 0]
# が↓こうなって
['khabarovsk', -int('20'), str(0 + 1)]
# [l[0],-int(l[1]),str(l[2]+1)]の解説
# ↓こうなります。
['khabarovsk', -20, 1]

-int('20'):マイナスにすることで昇順でソートできるようにします。
str(0 + 1):レストランの番号が1からスタートするので+1します。

sorted(
    [[l[0], -int(l[1]), str(l[2] + 1)] for l in (input().split() + [i] for i in range(int(input())))],
    key=lambda x: x[1]
)

先に点数でソートします。

[l[2] for l in sorted(
    sorted([[l[0], -int(l[1]), str(l[2] + 1)] for l in (input().split() + [i] for i in range(int(input())))], key=lambda x: x[1]),
    key=lambda x: x[0]
)]

次にレストラン名でソートし、レストランの番号を出力します。

print(
    '\n'.join(
        [l[2] for l in sorted(sorted([[l[0], -int(l[1]), str(l[2] + 1)] for l in (input().split() + [i] for i in range(int(input())))], key=lambda x: x[1]), key=lambda x: x[0])]
    )
)

最後に\nで連結し出力します。

ちなみに

ワンライナーじゃないですがitemgetterを使うとsortedが1回で済みます。

from operator import itemgetter
print('\n'.join([l[2] for l in sorted([[l[0], -int(l[1]), str(l[2] + 1)] for l in (input().split() + [i] for i in range(int(input())))],key=itemgetter(0, 1))]))
from operator import itemgetter
print(
    '\n'.join(
        [l[2] for l in sorted(
            [[l[0], -int(l[1]), str(l[2] + 1)] for l in (
                input().split() + [i] for i in range(
                    int(input())
                )
            )],
            key=itemgetter(0, 1)
        )]
    )
)
1
2
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?