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

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

ただいまの
回答率

90.87%

  • Python

    5889questions

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

  • ソート

    57questions

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

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

受付中

回答 8

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 404

問題
以下のようなデータ加工を行う関数作成してください。
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)
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • hayataka2049

    2018/05/15 18:50

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

    キャンセル

  • tachikoma

    2018/05/15 19:02

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

    キャンセル

  • tachikoma

    2018/05/15 19:30

    ありがとう〜

    キャンセル

回答 8

+4

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


スピードはこんな感じ。

#------LouiS0616さん回答
#後ろ半分を逆に並べて、前半分と交互に差し込む方法。
#成分が奇数個の場合の処理に大半のテクニックが使われている。
from itertools import chain, zip_longest
n = 10000
A = list(range(1, n+1))
ans = list((lambda elems:
            (lambda es, m: list(filter(None,
                                       chain(*zip_longest(es[:m],
                                                          es[m:][::-1]))))
            )(elems, len(elems) // 2)
           )(A)
          )
#454 µs ± 4.94 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

#------list.pop
#リストのpopで成分取り出し。
#pop(0)がO(N)
n = 10000
a = list(range(n))

ans = []
while True:
    try:
        ans.append(a.pop(0))
        ans.append(a.pop())
    except IndexError:
        break
#3.46 ms ± 4.17 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

#------deque.pop
#dequeのpopで成分取り出し。
#両端共にO(1)
from collections import deque

n = 10000
a = list(range(n))
a = deque(a)

ans = []
while True:
    try:
        ans.append(a.popleft())
        ans.append(a.pop())
    except IndexError:
        break
#942 µs ± 821 ns per loop (mean ± std. dev. of 7 runs, 100 loops each)

#------list.slice
#リストのsliceで成分取り出し。
#inplaceではなくコピーで時間がかかっているはず。
n = 10000
a = list(range(n))

ans = []
while True:
    try:
        ans.append(a[0])
        a = a[1:]
        ans.append(a[-1])
        a = a[:-1]
    except IndexError:
        break
#89 ms ± 278 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

#------reverse.pop
#後ろからしかpopしないと心に決める方法。
#取り出すごとにリストを逆順にならべかえる。
n = 10000
a = list(range(n))
a = a[::-1]

ans = []
while True:
    try:
        ans.append(a.pop())
        a = a[::-1]
    except IndexError:
        break
#94.4 ms ± 425 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

#------index
#popみたいな操作が遅いと疑ってみる方法。
#appendが遅いのがどうにもならないっぽい。
#dequeより遅いのはif文のせいか?(根拠なし)
n = 10000
a = list(range(n))

ans = []
i = 0
while True:
    ans.append(a[i])
    if len(ans)==n:
        break
    i += 1
    ans.append(a[-i])
    if len(ans)==n:
        break
#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 18:03

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

    キャンセル

  • 2018/05/15 18:11

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

    キャンセル

  • 2018/05/15 18:22

    YouheiSakuraiさん
    確かにリストでもいいですね。

    左と右の処理が異なるのが気になるかどうかという好みの問題でしょうか。

    リストの方がimportなしでできる利点がありますね。

    キャンセル

  • 2018/05/15 18:23

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

    キャンセル

  • 2018/05/15 18:26 編集

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

    キャンセル

  • 2018/05/15 18:27

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

    キャンセル

  • 2018/05/15 19:18

    hayataka2049さん、多分dequeの方が大きなデータを扱うときには速い気がします。https://docs.python.jp/3/library/collections.html#collections.deque

    キャンセル

  • 2018/05/15 19:31

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

    キャンセル

+3

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/15 19:07

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

    キャンセル

  • 2018/05/15 19:11

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

    キャンセル

  • 2018/05/15 19:18 編集

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

    キャンセル

+1

書いてみた。Wandbox

import 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 19:28

    https://wandbox.org/permlink/QRZFMySq4ef1icty
    https://wandbox.org/permlink/0j74dWH4NGueNxX7
    この違いってどうして起こるのでしょうか?

    キャンセル

  • 2018/05/15 19:40 編集

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

    現状では lambda e: e を渡しているのと同じです。

    キャンセル

  • 2018/05/15 19:40

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

    キャンセル

0

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ヒントだけ。

  • i =0~要素の個数分ループします。
  • iが偶数なら先頭から、奇数なら末尾からi/2番目(切り上げ)の要素を取ります。
l = ['str{}'.format(i+1) for i in range(7)]
print(l)

print(l[0])
print(l[-1])
print(l[1])
print(l[-2])
print(l[2])
print(l[-3])
print(l[3])

"""
for i in 0から要素の個数分:
    if i が偶数:
        先頭から i / 2 番目
    else:
        末尾から i / 2 番目
"""

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

from itertools import chain

data = """\
1aaa
2bbb
3ccc
4ddd
5eee
6fff
7ggg
""".splitlines()

print([*chain(*zip(data, data[::-1]))][:len(data)])

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

from math import cos, pi

ls = list(i + 1 for i in range(7))
back_and_forth = [ls[int((-cos(pi * i) ** 2 + cos(pi * i) * (1 + 2 * i)) / 4)] for i in range(len(ls))]

print(back_and_forth)
# [1, 7, 2, 6, 3, 5, 4]

repl.it demo

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.87%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python

    5889questions

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

  • ソート

    57questions

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

  • トップ
  • Pythonに関する質問
  • pythonで、先頭、最後、先頭から2番目、最後から2番目、・・・のように順番に並べる方法が分かりません