「R言語でのベクトル要素の削除」に似た処理をPythonで行いたい


目的・背景

個人的に,R言語におけるベクトル要素の削除と,Pythonにおけるリスト要素の削除(del文など使用)では勝手の異なる点が多く,困惑したことが何度かありました.例えば...

remove.R
tmp = c("a","b","c","d","e")
tmp2 = tmp[-3]
print(tmp)
print(tmp2)
# 出力
# "a" "b" "c" "d" "e"
# "a" "b" "d" "e"

このような処理をPythonで行おうと思って,次のコードを書いたことがあります.

remove.py
tmp = ["a","b","c","d","e"]
tmp2 = tmp
del tmp2[2]
print(tmp)
print(tmp2)
# 出力
# ['a', 'b', 'd', 'e']   # tmpからも"c"が消えてる...??と困惑した.
# ['a', 'b', 'd', 'e']

当時「tmpが指しているリストオブジェクトのアドレスがtmp2に渡される」ということを知らなかったため,Rをいじる感覚でPythonのコードを書いてしまい失敗したことが何度かありました.
そこで,タイトルのような関数をPythonで作ってそれを使っていこうと考えました.

ちなみに,Rでは次のようにインデックスを指定して複数の要素の削除も可能です.
このような指定,処理もできるような関数にしたいと思います.

remove2.R
tmp = c("a","b","c","d","e")
tmp2 = tmp[-c(2,3,4)]
print(tmp)
print(tmp2)
# 出力
# "a" "b" "c" "d" "e"
# "a" "e"

作った関数

作成した rdel() を定義するソースコードは,次のような感じです.
Rっぽい要素delete,という意味で rdel という名前にしました.

def_rdel.py
def rdel_1(lis,ind):
    n = len(lis)
    if ind==0:
        out = lis[1:(n-1)+1]
    elif ind==(n-1):
        out = lis[0:(n-2)+1]
    else:
        zen = lis[0:(ind-1)+1]
        kou = lis[(ind+1):(n-1)+1]
        out = zen + kou
    return out

def rdel(lis,ind):
    if type(ind)!=list:
        out = rdel_1(lis,ind)
    else:
        ind = sorted(ind)
        back = 1
        for i in range(len(ind)):
            lis = rdel_1(lis,ind[i])
            if i < len(ind)-1:
                ind[i+1] -= back
                back += 1
        out = lis
    return out

引数は次の通りです.

  • lis:リストオブジェクト.要素の削除の対象.
  • ind:int(またはそのリスト)オブジェクト.削除したい要素のインデックスを指定.

使用例を最後に示します.

ex_rdel.py
hoge = ["a","b","c","d"]
ex1 = rdel(hoge,2)
ex2 = rdel(hoge,[1,3])
print(hoge,ex1,ex2)
# 出力
# ['a', 'b', 'c', 'd'] ['a', 'b', 'd'] ['a', 'c']

エラー処理等は全然できていません.
アドバイスやご指摘がありましたらお願いいたします.