日韩性视频-久久久蜜桃-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)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 在线观看日韩视频 | 亚洲精品无码久久久久久久 | 麻豆影视 | 天天操精品 | 福利片第一页 | 色综合一区 | www.色多多 | 精品欧美一区二区精品少妇 | 中文字幕第315页 | 国产精品国产一区二区三区四区 | 在线综合av| 欧美激情视频在线观看 | 国产69精品麻豆 | 一二三四视频社区在线 | 91在线视频免费 | 黄色一级大片在线观看 | 日韩午夜免费视频 | 小柔的裸露日记h | 欧美日韩中字 | av免费的 | 欧洲色区| 蜜桃麻豆视频 | 欧美黑吊大战白妞 | 免费看黄色片子 | 日韩国产区 | 噜噜噜久久久 | 日韩三级大片 | 中文字幕精品一区二 | 91精品又粗又猛又爽 | 精品国产区 | 久久深夜视频 | 日本美女裸体视频 | 久久久精彩视频 | 国产又粗又猛又爽又黄的 | 黑人玩弄人妻一区二 | 韩国黄色视屏 | av福利站 | 午夜精品极品粉嫩国产尤物 | 美女av网址 | 麻豆精品网站 | 国产又爽又色 | 成人综合区| 亚洲久久在线 | 成人午夜天 | 国产无遮挡又黄又爽又色 | 日韩成年人视频 | 欧美大尺度床戏做爰 | 日本黄色一级视频 | 色婷婷麻豆 | 欧美69影院| 黄色三级图片 | 91成年人视频 | 波多野结衣一区二区在线 | 九九九热视频 | 粉嫩久久99精品久久久久久夜 | 亚洲一区在线视频观看 | 亚洲精品一区二区三区在线观看 | 色射视频 | 成年人免费高清视频 | 污在线观看| 一级片视频在线观看 | 国产精品99久久久久久人 | 中文字幕精品视频在线观看 | 中文天堂在线观看 | 亚洲 欧美 视频 | 亚洲爱爱网站 | 99精品视频免费在线观看 | 国产精品一区二区av白丝下载 | 成人在线高清视频 | 成人激情在线视频 | 图片区视频区小说区 | 亚洲欧美在线成人 | 毛片大片 | 69网站在线观看 | av55 | 免费高清av在线看 | 天天射天天操天天干 | 爱草在线视频 | 精品视频第一页 | 中文在线a在线 | 在线视频日韩精品 | 2019国产精品 | 久久4| 狠狠躁18三区二区一区视频 | 欧美成人h| 91av爱爱| 亚洲精品粉嫩小泬 | 日韩 欧美 精品 | 欧美黄色一级视频 | a视频在线看 | 大陆极品少妇内射aaaaa | 日韩人妻一区二区三区 | 5566毛片| 一区二区视频免费 | 国产v亚洲v天堂无码 | 啪啪网页 | 香蕉视频黄色在线观看 | 精品国产一区在线 | 女同av网站| 精品乱 |