質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

8回答

5221閲覧

pythonで、先頭、最後、先頭から2番目、最後から2番目、・・・のように順番に並べる方法が分かりません

SatoruShirasaka

総合スコア6

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/05/15 08:40

編集2018/05/15 10:17

問題
以下のようなデータ加工を行う関数作成してください。
input test1
1aaa
2bbb
3ccc
4ddd
5eee
6fff
7ggg

このデータを
1aaa
7ggg
2bbb
6fff
3ccc
5eee
4ddd
となるように加工したいです。

自分の中でやってみたこと:昇順と降順を足し合わせる

#先頭、最後、先頭から2番目、最後から2番目、...のように順番に並べる def readdata(): r = [] f = open('C:\python_study\test11.txt','r') for row in f.readlines(): r.append(row.replace('\n','')) f.close() return r def writedata(a): print(a) def tobbottomalt(a): r = [] for i in range(0,len(a),1): r.append(a[i]) return r def tobbottomalt(b): r = [] for i in reversed(range(0,len(a))): r.append(a[i]) return r data1 = readdata() data2 = tobbottomalt(data1) writedata(data2)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayataka2049

2018/05/15 08:50

問題の出典はどこですか?
LouiS0616

2018/05/15 08:53

未完成でも良いですから、コードを提示してください。
SatoruShirasaka

2018/05/15 08:54

会社の研修での課題なので、講師のオリジナルだと思います。
YasuhiroMiyake

2018/05/15 08:55

会社の研修をここで答えを調達するのは、その講師の方に意思ではないと思いますよ。
LouiS0616

2018/05/15 08:57

研修の課題なら、ご自身で解かないといけないのでは?むしろ解けないのなら『解けませんでした』としっかり伝えるべきです。解けるフリをされるのが一番困ります。
hayataka2049

2018/05/15 09:50

講師の方や会社の方がこのページを見たとして、あなたの不利益になりませんか?
tachikoma

2018/05/15 10:02

コードのインデントが崩れていて元のコードが読めないので、<code>のボタン使ってコードをかこって下さいな。
guest

回答8

0

注:研修の問題でしたか。
答えを載せちゃうのはまずかったかも。
ちゃんと理解することをお勧めします。
あとで困るのは自分自身なので。


スピードはこんな感じ。

python

1#------LouiS0616さん回答 2#後ろ半分を逆に並べて、前半分と交互に差し込む方法。 3#成分が奇数個の場合の処理に大半のテクニックが使われている。 4from itertools import chain, zip_longest 5n = 10000 6A = list(range(1, n+1)) 7ans = list((lambda elems: 8 (lambda es, m: list(filter(None, 9 chain(*zip_longest(es[:m], 10 es[m:][::-1])))) 11 )(elems, len(elems) // 2) 12 )(A) 13 ) 14#454 µs ± 4.94 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 15 16#------list.pop 17#リストのpopで成分取り出し。 18#pop(0)がO(N) 19n = 10000 20a = list(range(n)) 21 22ans = [] 23while True: 24 try: 25 ans.append(a.pop(0)) 26 ans.append(a.pop()) 27 except IndexError: 28 break 29#3.46 ms ± 4.17 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 30 31#------deque.pop 32#dequeのpopで成分取り出し。 33#両端共にO(1) 34from collections import deque 35 36n = 10000 37a = list(range(n)) 38a = deque(a) 39 40ans = [] 41while True: 42 try: 43 ans.append(a.popleft()) 44 ans.append(a.pop()) 45 except IndexError: 46 break 47#942 µs ± 821 ns per loop (mean ± std. dev. of 7 runs, 100 loops each) 48 49#------list.slice 50#リストのsliceで成分取り出し。 51#inplaceではなくコピーで時間がかかっているはず。 52n = 10000 53a = list(range(n)) 54 55ans = [] 56while True: 57 try: 58 ans.append(a[0]) 59 a = a[1:] 60 ans.append(a[-1]) 61 a = a[:-1] 62 except IndexError: 63 break 64#89 ms ± 278 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 65 66#------reverse.pop 67#後ろからしかpopしないと心に決める方法。 68#取り出すごとにリストを逆順にならべかえる。 69n = 10000 70a = list(range(n)) 71a = a[::-1] 72 73ans = [] 74while True: 75 try: 76 ans.append(a.pop()) 77 a = a[::-1] 78 except IndexError: 79 break 80#94.4 ms ± 425 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 81 82#------index 83#popみたいな操作が遅いと疑ってみる方法。 84#appendが遅いのがどうにもならないっぽい。 85#dequeより遅いのはif文のせいか?(根拠なし) 86n = 10000 87a = list(range(n)) 88 89ans = [] 90i = 0 91while True: 92 ans.append(a[i]) 93 if len(ans)==n: 94 break 95 i += 1 96 ans.append(a[-i]) 97 if len(ans)==n: 98 break 99#1.35 ms ± 2.62 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

※最初の回答
dequeに入れて、両端から交互にpopすればできます。


数字の0を含む場合のfilterの処理が気になる方が万が一いらっしゃれば、
https://stackoverflow.com/questions/16096754/remove-none-value-from-a-list-without-removing-the-0-value


結局LouiS0616さん回答やdequeの方法あたりまでくると、リストの生成に一番時間がかかっているので、直接lambda式で処理するのが速いようですね。
dequeの場合、一度dequeに入れなおす必要があって、その処理時間を削減できないので結果としてLouiS0616さん回答の約倍の時間がかかるようです。

個人的にはsliceの方がpopよりだいぶ遅いのは意外でした。(小並感)

それぞれの構造体の各処理速度が気になる方は、
https://wiki.python.org/moin/TimeComplexity

投稿2018/05/15 08:53

編集2018/05/15 22:51
mkgrei

総合スコア8560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YouheiSakurai

2018/05/15 09:03

「おー!deque」と思いましたけどlistのpopでも十分ですよね?
SatoruShirasaka

2018/05/15 09:11

回答ありがとうございます。 具体例を挙げて説明していただけるとうれしいです。 初心者のもので、すいません。
mkgrei

2018/05/15 09:22

YouheiSakuraiさん 確かにリストでもいいですね。 左と右の処理が異なるのが気になるかどうかという好みの問題でしょうか。 リストの方がimportなしでできる利点がありますね。
YouheiSakurai

2018/05/15 09:23

mkgreiさん、なるほど。そこを気にしたらdequeの方が良さそうですね。
hayataka2049

2018/05/15 09:26 編集

pop(), popleft()になるかpop(0), pop(-1)になるかの違いなので正直どっちでも良いような気がしました
mkgrei

2018/05/15 09:27

書いてみたら、そこまで気にならなかったですね…
hayataka2049

2018/05/15 10:31

その通りでした。勉強になりました
guest

0

面白そうだったのでワンライナーで書いてみました

Python

1A = [1,2,3,4,5,6,7,8] 2 3ans = [A[(i + 1) // 2 * (-1) ** i] for i in range(len(A))] 4# [1, 7, 2, 6, 3, 5, 4]

投稿2018/05/15 10:01

magichan

総合スコア15898

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2018/05/15 10:07

三項演算子使うより10文字短い…負けました
magichan

2018/05/15 10:11

おっ、can110さんと同じアルゴリズムでしたか。。。
can110

2018/05/15 10:18 編集

考えは同じです。あえて回答差し控えてましたが「~[A[((-1 if i%2 else 1)*i)//2]~」こんな感じでした…
guest

0

書いてみた。Wandbox

Python

1import sys; from itertools import chain, zip_longest; print(*(lambda elems: (lambda es, m: list(filter(None, chain(*zip_longest(es[:m], es[m:][::-1])))))(elems, len(elems) // 2))([line.strip() for line in sys.stdin.readlines()]), sep='\n')

答えを貰っても、なんで動いているかわからないとつまらないし、ためにもなりません。

自分自身で『わからない』ポイントを明確にし、調べる/尋ねるスキルを身につけましょう。
結局はこれも研修の目的の一つなんじゃないかと思います。

投稿2018/05/15 09:45

LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

LouiS0616

2018/05/15 10:40 編集

filterの第一引数にNoneを渡しているので、0がFalseと判断され弾かれているからです。 代わりに lambda e: e is not None を渡せば問題ないです。 現状では lambda e: e を渡しているのと同じです。
mkgrei

2018/05/15 10:40

言われてみれば、なるほど。 ありがとうございます。
guest

0

python

1from math import cos, pi 2 3ls = list(i + 1 for i in range(7)) 4back_and_forth = [ls[int((-cos(pi * i) ** 2 + cos(pi * i) * (1 + 2 * i)) / 4)] for i in range(len(ls))] 5 6print(back_and_forth) 7# [1, 7, 2, 6, 3, 5, 4]

repl.it demo

投稿2018/05/15 11:42

karamarimo

総合スコア2551

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

python

1from itertools import chain 2 3data = """\ 41aaa 52bbb 63ccc 74ddd 85eee 96fff 107ggg 11""".splitlines() 12 13print([*chain(*zip(data, data[::-1]))][:len(data)])

投稿2018/05/15 10:26

編集2018/05/15 10:28
YouheiSakurai

総合スコア6142

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Python

1l = [1,2,3,4,5,6,7,8] 2print([i for j in zip(l,list(l)[::-1]) for i in j][0:len(l)])

投稿2018/05/15 10:18

kazto

総合スコア7196

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ヒントだけ。

  • i =0~要素の個数分ループします。
  • iが偶数なら先頭から、奇数なら末尾からi/2番目(切り上げ)の要素を取ります。

Python

1l = ['str{}'.format(i+1) for i in range(7)] 2print(l) 3 4print(l[0]) 5print(l[-1]) 6print(l[1]) 7print(l[-2]) 8print(l[2]) 9print(l[-3]) 10print(l[3]) 11 12""" 13for i in 0から要素の個数分: 14 if i が偶数: 15 先頭から i / 2 番目 16 else: 17 末尾から i / 2 番目 18"""

投稿2018/05/15 09:29

can110

総合スコア38262

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ヒント。
たとえばリストの長さが10なら、5回loopして、毎回i番、10-i-1番の要素を空リストにappendすればできます。
長さが11のときは同様に5回ループしたあと、残った要素を最後にappendします。偶数か奇数かで変わってくる訳で。
たとえば、10//2とすると5, 11//2とすると5になります。//は整数の商の演算子です(あまりは切り捨て)。

これくらいで良いですか?

投稿2018/05/15 09:22

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問