日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

lua与python结合_Lua和Python:实现一个高效的List对象(3)

發(fā)布時間:2024/10/8 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lua与python结合_Lua和Python:实现一个高效的List对象(3) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這一篇介紹一些列表函數(shù)的實現(xiàn)。

取值

取值用法和Table一樣,用ls[idx]獲得列表的值;并且除了可以用正索引,還可以像Python一樣用負索引,如-1表示最后一個元素,-2表示倒數(shù)第2個元素等等,C層代碼如下:

// 取list指針#define checklist(L) (list_t*)luaL_checkudata(L, 1, LIST_MT)// ls[idx]static int list_index(lua_State *L) {

list_t *ls = checklist(L);

int idx = (int)luaL_checkinteger(L, 2);

if (idx > 0) idx--; // 正索引 else if (idx < 0) idx += ls->size; // 負索引 if (idx < 0 || idx >= ls->size) { // 超出范圍的一律返回nil lua_pushnil(L);

return 1;

}

int ref = ls->ary[idx].ref; // 取引用值 lua_getuservalue(L, 1); // 將list的關(guān)聯(lián)Table放到棧上 lua_rawgeti(L, -1, ref); // 通過引用取Table的值,并返回 return 1;

}

設(shè)值

對列表設(shè)值必須限定在長度之內(nèi),超出會拋出錯誤,唯一的例外是在列表最后設(shè)值,那樣將認為是往后面追加,比如這樣寫:ls[#ls+1] = "ok"。

不能將nil設(shè)置給列表,因為Lua認為設(shè)置nil是刪除元素,要達到類似的需求,可給列表設(shè)置false。

設(shè)值和取值一樣支持負索引。

// ls[idx] = vstatic int list_newindex(lua_State *L) {

list_t *ls = checklist(L);

int idx = (int)luaL_checkinteger(L, 2);

if (idx > 0) idx--; // 正索引 else if (idx < 0) idx += ls->size; // 負索引 luaL_argcheck(L, 0 <= idx && idx <= ls->size, 2, "index out of range"); // 范圍檢查 if (lua_isnoneornil(L, 3)) // 不允許設(shè)置為nil luaL_argerror(L, 3, "value can not be nil");

lua_getuservalue(L, 1); // 將list的關(guān)聯(lián)Table放到棧上 lua_pushvalue(L, 3); // 將設(shè)置的值壓棧 if (idx == ls->size) { // 往后追加 check_and_grow_size(ls, 1);

ls->ary[ls->size++].ref = ref_value(L, ls, -2);

} else { // 正常設(shè)值 lua_rawseti(L, -2, ls->ary[idx].ref);

}

return 0;

}

check_and_grow_size檢查數(shù)組的內(nèi)存是否夠用,不夠會按2倍來擴展內(nèi)存:

static void check_and_grow_size(list_t *ls, int n) {

int newcap = ls->cap;

while (ls->size + n > newcap)

newcap <<= 1;

if (newcap != ls->cap) {

ls->ary = (refdata_t*)realloc(ls->ary, newcap*sizeof(refdata_t));

ls->cap = newcap;

}

}

取值/設(shè)值由于用了元表的方法,多了一個間接層,必然比直接訪問Table要慢一點。

取列表長度

按Lua的習慣,取長度用#ls,只需將list的size返回即可,效率比Table取長度要快得多:

// #lsstatic int list_len(lua_State *L) {

list_t *ls = checklist(L);

lua_pushinteger(L, ls->size);

return 1;

}

清除列表內(nèi)容

直接將list的size置0即可,對于關(guān)聯(lián)的Table,干脆拋棄它,直接新建一個Table關(guān)聯(lián):

// list.clear(ls[, shink])static int list_clear(lua_State *L) {

list_t *ls = checklist(L);

int shink = lua_toboolean(L, 2); // 如果指定shink,會收縮內(nèi)存 ls->size = 0; // 直接置0 ls->ref = 0;

if (shink) {

ls->cap = 4;

ls->ary = (refdata_t*)realloc(ls->ary, ls->cap * sizeof(refdata_t));

}

lua_createtable(L, ls->cap, 0); // 重新創(chuàng)建Table,替換掉老的Table,老Table會被Lua自動GC回收掉。 lua_setuservalue(L, 1);

return 0;

}

交換兩個位置的元素

這同樣是一個很高效的操作,不需要涉及到Table的操作,直接將兩個引用交換:

// list.exchange(ls, idx1, idx2)static int list_exchange(lua_State *L) {

list_t *ls = checklist(L);

int idx1 = (int)luaL_checkinteger(L, 2) - 1;

int idx2 = (int)luaL_checkinteger(L, 3) - 1;

if (idx1 == idx2) return 0;

luaL_argcheck(L, 0 <= idx1 && idx1 < ls->size, 2, "index out of range");

luaL_argcheck(L, 0 <= idx2 && idx2 < ls->size, 3, "index out of range");

refdata_t ref = ls->ary[idx1]; // 交換引用即可 ls->ary[idx1] = ls->ary[idx2];

ls->ary[idx2] = ref;

return 0;

}

插入元素

接口和table.insert一樣,如果不指定pos則往后插入,如果指定則插入到pos位置:

// list.insert(ls, [pos,] value)static int list_insert(lua_State *L) {

list_t *ls = checklist(L);

int pos, n, vidx;

if (lua_gettop(L) == 2) { // 只有兩個參數(shù),則認為沒有指定pos,pos設(shè)置為size pos = ls->size;

vidx = 2;

} else { // 有指定pos pos = (int)luaL_checkinteger(L, 2) - 1;

vidx = 3;

}

if (lua_isnoneornil(L, vidx)) // 不允許設(shè)置nil luaL_argerror(L, vidx, "value can not be nil");

// 檢查pos的合法性 luaL_argcheck(L, 0 <= pos && pos <= ls->size, 2, "index out of range");

// 檢查和增長內(nèi)存 check_and_grow_size(ls, 1);

// 如果不是往后插入,則要移動內(nèi)存 if (pos != ls->size)

memmove(ls->ary + pos + 1, ls->ary + pos, (ls->size - pos) * sizeof(refdata_t));

lua_getuservalue(L, 1); // 取關(guān)聯(lián)Table lua_pushvalue(L, vidx); // 將要設(shè)置的值入棧 ls->ary[pos].ref = ref_value(L, ls, -2); // 將值設(shè)為Table,同時返回一個引用,保存到數(shù)組。 ls->size++;

return 0;

}

我們后面的操作都是對引用的操作,Table只是設(shè)值和去除值。

刪除元素

接口和table.remove一樣,如果不指定pos則從最后刪除,如果指定則刪除pos的值,最后返回刪除的值

// list.remove(ls[, pos]) -> vstatic int list_remove(lua_State *L) {

list_t *ls = checklist(L);

int pos = luaL_optinteger(L, 2, ls->size) - 1;

luaL_argcheck(L, 0 <= pos && pos < ls->size, 2, "index out of range");

int ref = ls->ary[pos].ref;

// 如果不是刪除最后一個,則要移動內(nèi)存 if (pos != ls->size - 1)

memmove(ls->ary + pos, ls->ary + pos + 1, (ls->size - pos - 1) * sizeof(refdata_t));

ls->size--;

lua_getuservalue(L, 1); // 取關(guān)聯(lián)Table lua_rawgeti(L, -1, ref); // 將要刪除的值取出,返回 unref_value(L, -2, ref); // 刪除值,解除引用 return 1;

}

其他接口

除了上面的函數(shù),還有其他的接口,這里就不一一介紹了,我最后會把完整代碼共享出來。

下一篇單獨把排序拿出來說,并給出一個高效的實現(xiàn)。

總結(jié)

以上是生活随笔為你收集整理的lua与python结合_Lua和Python:实现一个高效的List对象(3)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩中文字 | 国产精品久久久久久久久晋中 | 中文字幕av专区 | 激情综合视频 | 一级片免费观看视频 | 中文字幕一区二区三区在线不卡 | www.视频一区| 久久精品无码一区二区三区免费 | 欧美性极品少妇xxxx | 精品国产乱码久久久久久88av | 国产综合久久 | 成人在线观看一区 | 99只有精品 | 欧美两根一起进3p做受视频 | 超碰个人在线 | 国产在线一区二区视频 | 免费在线观看国产精品 | 国产精品传媒一区二区 | 夜夜爽妓女8888视频免费观看 | 福利在线影院 | 国产一区一一区高清不卡 | 中国老熟女重囗味hdxx | 国产精品v亚洲精品v日韩精品 | 国产精品12区 | 久久国产精品久久国产精品 | 91九色国产 | 精品亚洲天堂 | 中文有码视频 | 91啦中文 | 香蕉久久夜色精品升级完成 | 大学生三级中国dvd 日韩欧美一区二区区 | 国产a级淫片 | 轻点好疼好大好爽视频 | 中文字幕在线观看不卡 | 亚洲欧美成人 | 在线a网| 性av免费 | 潘金莲一级淫片aaaaaa播放 | 国产麻豆剧传媒精品国产av | 中字幕一区二区三区乱码 | 黄色网址哪里有 | 91看视频 | 麻豆精品一区二区 | 黄色av日韩 | 日本a∨视频 | www.av小说 | 一区二区三区四区在线视频 | 99riav国产精品视频 | 国产精品久久久久久久一区探花 | 樱花动漫无圣光 | 亚洲精品国产精品乱码桃花 | 中日韩在线观看视频 | 女大学生的家政保姆初体验 | 亚洲精品视频免费看 | 亚洲不卡av一区二区 | 久久噜噜色综合一区二区 | 欧美一级片一区二区 | 曰本丰满熟妇xxxx性 | 免费在线黄色av | 免费在线观看网址入口 | 天天曰天天操 | 欧美嫩草 | 久久精品色欲国产AV一区二区 | 国产一区二区播放 | 三男一女吃奶添下面 | 天天摸天天做天天爽水多 | 黄色伊人 | 国产最新自拍视频 | 又大又粗欧美黑人aaaaa片 | 电影一区二区三区 | 亚洲色图导航 | 国产成人三级一区二区在线观看一 | 亚洲剧情av| 日日鲁鲁鲁夜夜爽爽狠狠视频97 | 午夜高清 | 亚洲快播 | 超碰在线免费看 | 国产最新视频 | 精品国产成人av | av色片 | 男生插女生的视频 | 探花国产精品一区二区 | 成人伊人网站 | 国产淫语对白 | 亚洲伦理中文字幕 | 天天操天天干天天摸 | av高清在线 | 日本超碰在线 | 欧美成人高清在线 | 毛片专区| 成人福利一区二区三区 | 久久人妻一区二区 | 3o一40一50一6o女人毛片 | 3d动漫精品啪啪一区二区下载 | 日韩在线免费观看视频 | 中文字幕人成乱码熟女香港 | 免费www xxx | 激情伊人 | 国产乱淫av片杨贵妃 |